Merge branch upstream/master while introducing compile errors and reverting parts of Android changes, video BPP options are gone
This commit is contained in:
1
src/3rdparty/CMakeLists.txt
vendored
1
src/3rdparty/CMakeLists.txt
vendored
@@ -1,3 +1,4 @@
|
||||
add_subdirectory(fmt)
|
||||
add_subdirectory(md5)
|
||||
add_subdirectory(squirrel)
|
||||
add_subdirectory(opengl)
|
||||
|
||||
5
src/3rdparty/fmt/CMakeLists.txt
vendored
Normal file
5
src/3rdparty/fmt/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
add_files(
|
||||
core.h
|
||||
format.h
|
||||
format-inl.h
|
||||
)
|
||||
27
src/3rdparty/fmt/LICENSE.rst
vendored
Normal file
27
src/3rdparty/fmt/LICENSE.rst
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2012 - present, Victor Zverovich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--- Optional exception to the license ---
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into a machine-executable object form of such
|
||||
source code, you may redistribute such embedded portions in such object form
|
||||
without including the above copyright and permission notices.
|
||||
2122
src/3rdparty/fmt/core.h
vendored
Normal file
2122
src/3rdparty/fmt/core.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2801
src/3rdparty/fmt/format-inl.h
vendored
Normal file
2801
src/3rdparty/fmt/format-inl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3960
src/3rdparty/fmt/format.h
vendored
Normal file
3960
src/3rdparty/fmt/format.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4
src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp
vendored
4
src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp
vendored
@@ -17,7 +17,7 @@ void sqstd_printcallstack(HSQUIRRELVM v)
|
||||
SQFloat f;
|
||||
const SQChar *s;
|
||||
SQInteger level=1; //1 is to skip this function that is level 0
|
||||
const SQChar *name=0;
|
||||
const SQChar *name=nullptr;
|
||||
SQInteger seq=0;
|
||||
pf(v,"\nCALLSTACK\n");
|
||||
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
|
||||
@@ -116,7 +116,7 @@ static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
|
||||
{
|
||||
SQPRINTFUNCTION pf = sq_getprintfunc(v);
|
||||
if(pf) {
|
||||
const SQChar *sErr = 0;
|
||||
const SQChar *sErr = nullptr;
|
||||
if(sq_gettop(v)>=1) {
|
||||
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
|
||||
pf(v,"\nAN ERROR HAS OCCURRED [%s]\n",sErr);
|
||||
|
||||
4
src/3rdparty/squirrel/sqstdlib/sqstdmath.cpp
vendored
4
src/3rdparty/squirrel/sqstdlib/sqstdmath.cpp
vendored
@@ -88,7 +88,7 @@ static SQRegFunction mathlib_funcs[] = {
|
||||
#endif /* EXPORT_DEFAULT_SQUIRREL_FUNCTIONS */
|
||||
_DECL_FUNC(fabs,2,".n"),
|
||||
_DECL_FUNC(abs,2,".n"),
|
||||
{0,0,0,0},
|
||||
{nullptr,nullptr,0,nullptr},
|
||||
};
|
||||
|
||||
#ifndef M_PI
|
||||
@@ -98,7 +98,7 @@ static SQRegFunction mathlib_funcs[] = {
|
||||
SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
|
||||
{
|
||||
SQInteger i=0;
|
||||
while(mathlib_funcs[i].name!=0) {
|
||||
while(mathlib_funcs[i].name!=nullptr) {
|
||||
sq_pushstring(v,mathlib_funcs[i].name,-1);
|
||||
sq_newclosure(v,mathlib_funcs[i].f,0);
|
||||
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
|
||||
|
||||
58
src/3rdparty/squirrel/squirrel/sqapi.cpp
vendored
58
src/3rdparty/squirrel/squirrel/sqapi.cpp
vendored
@@ -60,11 +60,11 @@ HSQUIRRELVM sq_open(SQInteger initialstacksize)
|
||||
v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
|
||||
new (v) SQVM(ss);
|
||||
ss->_root_vm = v;
|
||||
if(v->Init(NULL, initialstacksize)) {
|
||||
if(v->Init(nullptr, initialstacksize)) {
|
||||
return v;
|
||||
} else {
|
||||
sq_delete(v, SQVM);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
@@ -83,7 +83,7 @@ HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
|
||||
return v;
|
||||
} else {
|
||||
sq_delete(v, SQVM);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ void sq_close(HSQUIRRELVM v)
|
||||
SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
|
||||
{
|
||||
SQObjectPtr o;
|
||||
if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
|
||||
if(Compile(v, read, p, sourcename, o, raiseerror != 0, _ss(v)->_debuginfo)) {
|
||||
v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
|
||||
return SQ_OK;
|
||||
}
|
||||
@@ -144,12 +144,12 @@ SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQCha
|
||||
|
||||
void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
|
||||
{
|
||||
_ss(v)->_debuginfo = enable?true:false;
|
||||
_ss(v)->_debuginfo = enable != 0;
|
||||
}
|
||||
|
||||
void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
|
||||
{
|
||||
_ss(v)->_notifyallexceptions = enable?true:false;
|
||||
_ss(v)->_notifyallexceptions = enable != 0;
|
||||
}
|
||||
|
||||
void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
|
||||
@@ -178,7 +178,7 @@ const SQChar *sq_objtostring(HSQOBJECT *o)
|
||||
if(sq_type(*o) == OT_STRING) {
|
||||
return _stringval(*o);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SQInteger sq_objtointeger(HSQOBJECT *o)
|
||||
@@ -224,7 +224,7 @@ void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
|
||||
|
||||
void sq_pushbool(HSQUIRRELVM v,SQBool b)
|
||||
{
|
||||
v->Push(b?true:false);
|
||||
v->Push(b != 0);
|
||||
}
|
||||
|
||||
void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
|
||||
@@ -256,7 +256,7 @@ void sq_newarray(HSQUIRRELVM v,SQInteger size)
|
||||
|
||||
SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
|
||||
{
|
||||
SQClass *baseclass = NULL;
|
||||
SQClass *baseclass = nullptr;
|
||||
if(hasbase) {
|
||||
SQObjectPtr &base = stack_get(v,-1);
|
||||
if(type(base) != OT_CLASS)
|
||||
@@ -555,7 +555,7 @@ SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
|
||||
|
||||
SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_STRING,o);
|
||||
*c = _stringval(*o);
|
||||
return SQ_OK;
|
||||
@@ -563,7 +563,7 @@ SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
|
||||
|
||||
SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_THREAD,o);
|
||||
*thread = _thread(*o);
|
||||
return SQ_OK;
|
||||
@@ -598,7 +598,7 @@ SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
|
||||
|
||||
SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_USERDATA,o);
|
||||
(*p) = _userdataval(*o);
|
||||
if(typetag) *typetag = _userdata(*o)->_typetag;
|
||||
@@ -637,7 +637,7 @@ SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
|
||||
|
||||
SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
|
||||
(*p) = _userpointer(*o);
|
||||
return SQ_OK;
|
||||
@@ -666,13 +666,13 @@ SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserP
|
||||
SQObjectPtr &o = stack_get(v,idx);
|
||||
if(type(o) != OT_INSTANCE) return sq_throwerror(v,"the object is not a class instance");
|
||||
(*p) = _instance(o)->_userpointer;
|
||||
if(typetag != 0) {
|
||||
if(typetag != nullptr) {
|
||||
SQClass *cl = _instance(o)->_class;
|
||||
do{
|
||||
if(cl->_typetag == typetag)
|
||||
return SQ_OK;
|
||||
cl = cl->_base;
|
||||
}while(cl != NULL);
|
||||
}while(cl != nullptr);
|
||||
return sq_throwerror(v,"invalid type tag");
|
||||
}
|
||||
return SQ_OK;
|
||||
@@ -724,7 +724,7 @@ SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
|
||||
if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
|
||||
SQObjectPtr &key = v->GetUp(-2);
|
||||
if(type(key) == OT_NULL) return sq_throwerror(v, "null is not a valid key");
|
||||
v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
|
||||
v->NewSlot(self, key, v->GetUp(-1),bstatic != 0);
|
||||
v->Pop(2);
|
||||
}
|
||||
return SQ_OK;
|
||||
@@ -801,14 +801,14 @@ SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
|
||||
if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, "delagate cycle");
|
||||
v->Pop();}
|
||||
else if(type(mt)==OT_NULL) {
|
||||
_table(self)->SetDelegate(NULL); v->Pop(); }
|
||||
_table(self)->SetDelegate(nullptr); v->Pop(); }
|
||||
else return sq_aux_invalidtype(v,type);
|
||||
break;
|
||||
case OT_USERDATA:
|
||||
if(type(mt)==OT_TABLE) {
|
||||
_userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
|
||||
else if(type(mt)==OT_NULL) {
|
||||
_userdata(self)->SetDelegate(NULL); v->Pop(); }
|
||||
_userdata(self)->SetDelegate(nullptr); v->Pop(); }
|
||||
else return sq_aux_invalidtype(v, type);
|
||||
break;
|
||||
default:
|
||||
@@ -909,7 +909,7 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
|
||||
}
|
||||
SQVM::CallInfo &ci=v->_callsstack[lvl];
|
||||
if(type(ci._closure)!=OT_CLOSURE)
|
||||
return NULL;
|
||||
return nullptr;
|
||||
SQClosure *c=_closure(ci._closure);
|
||||
SQFunctionProto *func=_funcproto(c->_function);
|
||||
if(func->_noutervalues > (SQInteger)idx) {
|
||||
@@ -919,7 +919,7 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
|
||||
idx -= func->_noutervalues;
|
||||
return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
|
||||
@@ -929,7 +929,7 @@ void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
|
||||
|
||||
void sq_resetobject(HSQOBJECT *po)
|
||||
{
|
||||
po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
|
||||
po->_unVal.pUserPointer=nullptr;po->_type=OT_NULL;
|
||||
}
|
||||
|
||||
SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
|
||||
@@ -975,7 +975,7 @@ SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror,
|
||||
v->_can_suspend = suspend >= 0;
|
||||
if (v->_can_suspend) v->_ops_till_suspend = suspend;
|
||||
|
||||
if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false,v->_can_suspend)){
|
||||
if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror != 0,v->_can_suspend)){
|
||||
if(!v->_suspended) {
|
||||
v->Pop(params);//pop closure and args
|
||||
}
|
||||
@@ -1051,7 +1051,7 @@ void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
|
||||
|
||||
SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
|
||||
unsigned short tag = SQ_BYTECODE_STREAM_TAG;
|
||||
if(w(up,&tag,2) != 2)
|
||||
@@ -1093,7 +1093,7 @@ SQInteger sq_collectgarbage(HSQUIRRELVM v)
|
||||
const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
|
||||
{
|
||||
SQObjectPtr &self = stack_get(v,idx);
|
||||
const SQChar *name = NULL;
|
||||
const SQChar *name = nullptr;
|
||||
if(type(self) == OT_CLOSURE) {
|
||||
if(_closure(self)->_outervalues.size()>nval) {
|
||||
v->Push(_closure(self)->_outervalues[nval]);
|
||||
@@ -1131,7 +1131,7 @@ SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
|
||||
|
||||
SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||
SQObjectPtr &key = stack_get(v,-2);
|
||||
SQObjectPtr &val = stack_get(v,-1);
|
||||
@@ -1153,7 +1153,7 @@ SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
|
||||
|
||||
SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||
SQObjectPtr &key = stack_get(v,-1);
|
||||
SQObjectPtr attrs;
|
||||
@@ -1173,7 +1173,7 @@ SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
|
||||
|
||||
SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||
if(_class(*o)->_base)
|
||||
v->Push(SQObjectPtr(_class(*o)->_base));
|
||||
@@ -1184,7 +1184,7 @@ SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
|
||||
|
||||
SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
|
||||
v->Push(SQObjectPtr(_instance(*o)->_class));
|
||||
return SQ_OK;
|
||||
@@ -1192,7 +1192,7 @@ SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
|
||||
|
||||
SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
|
||||
{
|
||||
SQObjectPtr *o = NULL;
|
||||
SQObjectPtr *o = nullptr;
|
||||
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
|
||||
v->Push(_class(*o)->CreateInstance());
|
||||
return SQ_OK;
|
||||
|
||||
50
src/3rdparty/squirrel/squirrel/sqbaselib.cpp
vendored
50
src/3rdparty/squirrel/squirrel/sqbaselib.cpp
vendored
@@ -248,29 +248,29 @@ static SQRegFunction base_funcs[]={
|
||||
{"getconsttable",base_getconsttable,1, NULL},
|
||||
{"setconsttable",base_setconsttable,2, NULL},
|
||||
#endif
|
||||
{"assert",base_assert,2, NULL},
|
||||
{"print",base_print,2, NULL},
|
||||
{"assert",base_assert,2, nullptr},
|
||||
{"print",base_print,2, nullptr},
|
||||
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
|
||||
{"compilestring",base_compilestring,-2, ".ss"},
|
||||
{"newthread",base_newthread,2, ".c"},
|
||||
{"suspend",base_suspend,-1, NULL},
|
||||
#endif
|
||||
{"array",base_array,-2, ".n"},
|
||||
{"type",base_type,2, NULL},
|
||||
{"type",base_type,2, nullptr},
|
||||
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
|
||||
{"dummy",base_dummy,0,NULL},
|
||||
#ifndef NO_GARBAGE_COLLECTOR
|
||||
{"collectgarbage",base_collectgarbage,1, "t"},
|
||||
#endif
|
||||
#endif
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
void sq_base_register(HSQUIRRELVM v)
|
||||
{
|
||||
SQInteger i=0;
|
||||
sq_pushroottable(v);
|
||||
while(base_funcs[i].name!=0) {
|
||||
while(base_funcs[i].name!=nullptr) {
|
||||
sq_pushstring(v,base_funcs[i].name,-1);
|
||||
sq_newclosure(v,base_funcs[i].f,0);
|
||||
sq_setnativeclosurename(v,-1,base_funcs[i].name);
|
||||
@@ -415,10 +415,10 @@ SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
|
||||
{"rawset",table_rawset,3, "t"},
|
||||
{"rawdelete",table_rawdelete,2, "t"},
|
||||
{"rawin",container_rawexists,2, "t"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{"clear",obj_clear,1, "."},
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
//ARRAY DEFAULT DELEGATE///////////////////////////////////////
|
||||
@@ -624,10 +624,10 @@ SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
|
||||
{"reverse",array_reverse,1, "a"},
|
||||
{"sort",array_sort,-1, "ac"},
|
||||
{"slice",array_slice,-1, "ann"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{"clear",obj_clear,1, "."},
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
//STRING DEFAULT DELEGATE//////////////////////////
|
||||
@@ -687,8 +687,8 @@ SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
|
||||
{"find",string_find,-2, "s s n "},
|
||||
{"tolower",string_tolower,1, "s"},
|
||||
{"toupper",string_toupper,1, "s"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{0,0,0,0}
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
//INTEGER DEFAULT DELEGATE//////////////////////////
|
||||
@@ -697,8 +697,8 @@ SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
|
||||
{"tofloat",default_delegate_tofloat,1, "n|b"},
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{"tochar",number_delegate_tochar,1, "n|b"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{0,0,0,0}
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
//CLOSURE DEFAULT DELEGATE//////////////////////////
|
||||
@@ -782,11 +782,11 @@ SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
|
||||
{"pcall",closure_pcall,-1, "c"},
|
||||
{"acall",closure_acall,2, "ca"},
|
||||
{"pacall",closure_pacall,2, "ca"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{"bindenv",closure_bindenv,2, "c x|y|t"},
|
||||
{"getinfos",closure_getinfos,1, "c"},
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
//GENERATOR DEFAULT DELEGATE
|
||||
@@ -803,9 +803,9 @@ static SQInteger generator_getstatus(HSQUIRRELVM v)
|
||||
|
||||
SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
|
||||
{"getstatus",generator_getstatus,1, "g"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
//THREAD DEFAULT DELEGATE
|
||||
@@ -889,9 +889,9 @@ SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
|
||||
{"call", thread_call, -1, "v"},
|
||||
{"wakeup", thread_wakeup, -1, "v"},
|
||||
{"getstatus", thread_getstatus, 1, "v"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{0,0,0,0},
|
||||
{nullptr,nullptr,0,nullptr},
|
||||
};
|
||||
|
||||
static SQInteger class_getattributes(HSQUIRRELVM v)
|
||||
@@ -919,10 +919,10 @@ SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
|
||||
{"getattributes", class_getattributes, 2, "y."},
|
||||
{"setattributes", class_setattributes, 3, "y.."},
|
||||
{"rawin",container_rawexists,2, "y"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{"instance",class_instance,1, "y"},
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
static SQInteger instance_getclass(HSQUIRRELVM v)
|
||||
@@ -935,9 +935,9 @@ static SQInteger instance_getclass(HSQUIRRELVM v)
|
||||
SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
|
||||
{"getclass", instance_getclass, 1, "x"},
|
||||
{"rawin",container_rawexists,2, "x"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
static SQInteger weakref_ref(HSQUIRRELVM v)
|
||||
@@ -949,9 +949,9 @@ static SQInteger weakref_ref(HSQUIRRELVM v)
|
||||
|
||||
SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
|
||||
{"ref",weakref_ref,1, "r"},
|
||||
{"weakref",obj_delegate_weakref,1, NULL },
|
||||
{"weakref",obj_delegate_weakref,1, nullptr },
|
||||
{"tostring",default_delegate_tostring,1, "."},
|
||||
{0,0,0,0}
|
||||
{nullptr,nullptr,0,nullptr}
|
||||
};
|
||||
|
||||
|
||||
|
||||
18
src/3rdparty/squirrel/squirrel/sqclass.cpp
vendored
18
src/3rdparty/squirrel/squirrel/sqclass.cpp
vendored
@@ -15,8 +15,8 @@
|
||||
SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
||||
{
|
||||
_base = base;
|
||||
_typetag = 0;
|
||||
_hook = NULL;
|
||||
_typetag = nullptr;
|
||||
_hook = nullptr;
|
||||
_udsize = 0;
|
||||
_metamethods.resize(MT_LAST); //size it to max size
|
||||
if(_base) {
|
||||
@@ -34,7 +34,13 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base)
|
||||
|
||||
void SQClass::Finalize() {
|
||||
_attributes = _null_;
|
||||
_defaultvalues.resize(0);
|
||||
/* SQInstance's Finalize depends on the size of this sqvector, so instead of
|
||||
* resizing, all SQObjectPtrs are set to "null" so it holds no references to
|
||||
* other objects anymore. That way everything gets released properly. */
|
||||
for (SQUnsignedInteger i = 0; i < _defaultvalues.size(); i++) {
|
||||
_defaultvalues[i].val = _null_;
|
||||
_defaultvalues[i].attrs = _null_;
|
||||
}
|
||||
_methods.resize(0);
|
||||
_metamethods.resize(0);
|
||||
__ObjRelease(_members);
|
||||
@@ -133,8 +139,8 @@ bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void SQInstance::Init(SQSharedState *ss)
|
||||
{
|
||||
_userpointer = NULL;
|
||||
_hook = NULL;
|
||||
_userpointer = nullptr;
|
||||
_hook = nullptr;
|
||||
__ObjAddRef(_class);
|
||||
_delegate = _class->_members;
|
||||
INIT_CHAIN();
|
||||
@@ -190,7 +196,7 @@ bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
|
||||
bool SQInstance::InstanceOf(SQClass *trg)
|
||||
{
|
||||
SQClass *parent = _class;
|
||||
while(parent != NULL) {
|
||||
while(parent != nullptr) {
|
||||
if(parent == trg)
|
||||
return true;
|
||||
parent = parent->_base;
|
||||
|
||||
2
src/3rdparty/squirrel/squirrel/sqclosure.h
vendored
2
src/3rdparty/squirrel/squirrel/sqclosure.h
vendored
@@ -45,7 +45,7 @@ struct SQGenerator : public CHAINABLE_OBJ
|
||||
{
|
||||
enum SQGeneratorState{eRunning,eSuspended,eDead};
|
||||
private:
|
||||
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
|
||||
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=nullptr;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
|
||||
public:
|
||||
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
|
||||
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));
|
||||
|
||||
@@ -57,7 +57,7 @@ typedef sqvector<ExpState> ExpStateVec;
|
||||
class SQCompiler
|
||||
{
|
||||
public:
|
||||
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(NULL), _lex(_ss(v), rg, up, ThrowError, this), _debugline(0), _debugop(0)
|
||||
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(nullptr), _lex(_ss(v), rg, up, ThrowError, this), _debugline(0), _debugop(0)
|
||||
{
|
||||
_vm=v;
|
||||
_sourcename = SQString::Create(_ss(v), sourcename);
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
_debugline = 1;
|
||||
_debugop = 0;
|
||||
|
||||
SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
|
||||
SQFuncState funcstate(_ss(_vm), nullptr,ThrowError,this);
|
||||
funcstate._name = SQString::Create(_ss(_vm), "main");
|
||||
_fs = &funcstate;
|
||||
_fs->AddParameter(_fs->CreateString("this"));
|
||||
@@ -835,8 +835,7 @@ public:
|
||||
nkeys++;
|
||||
SQInteger val = _fs->PopTarget();
|
||||
SQInteger key = _fs->PopTarget();
|
||||
SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
|
||||
(void)attrs; // assert only
|
||||
[[maybe_unused]] SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
|
||||
assert((hasattrs && attrs == key-1) || !hasattrs);
|
||||
unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
|
||||
SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
|
||||
|
||||
@@ -79,7 +79,7 @@ SQInstructionDesc g_InstrDesc[]={
|
||||
{"_OP_NEWSLOTA"},
|
||||
{"_OP_SCOPE_END"}
|
||||
};
|
||||
#endif
|
||||
|
||||
void DumpLiteral(SQObjectPtr &o)
|
||||
{
|
||||
switch(type(o)){
|
||||
@@ -90,6 +90,7 @@ void DumpLiteral(SQObjectPtr &o)
|
||||
default: printf("(%s %p)",GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
|
||||
{
|
||||
|
||||
4
src/3rdparty/squirrel/squirrel/sqlexer.cpp
vendored
4
src/3rdparty/squirrel/squirrel/sqlexer.cpp
vendored
@@ -87,7 +87,7 @@ SQLexer::SQLexer(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerE
|
||||
_prevtoken = -1;
|
||||
_curtoken = -1;
|
||||
|
||||
_svalue = NULL;
|
||||
_svalue = nullptr;
|
||||
_nvalue = 0;
|
||||
_fvalue = 0;
|
||||
|
||||
@@ -119,7 +119,7 @@ const SQChar *SQLexer::Tok2Str(SQInteger tok)
|
||||
if(((SQInteger)_integer(val)) == tok)
|
||||
return _stringval(key);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SQLexer::LexBlockComment()
|
||||
|
||||
10
src/3rdparty/squirrel/squirrel/sqobject.cpp
vendored
10
src/3rdparty/squirrel/squirrel/sqobject.cpp
vendored
@@ -41,7 +41,7 @@ const SQChar *IdType2Name(SQObjectType type)
|
||||
case _RT_INSTANCE: return "instance";
|
||||
case _RT_WEAKREF: return "weakref";
|
||||
default:
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,13 +101,13 @@ SQRefCounted::~SQRefCounted()
|
||||
{
|
||||
if(_weakref) {
|
||||
_weakref->_obj._type = OT_NULL;
|
||||
_weakref->_obj._unVal.pRefCounted = NULL;
|
||||
_weakref->_obj._unVal.pRefCounted = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SQWeakRef::Release() {
|
||||
if(ISREFCOUNTED(_obj._type)) {
|
||||
_obj._unVal.pRefCounted->_weakref = NULL;
|
||||
_obj._unVal.pRefCounted->_weakref = nullptr;
|
||||
}
|
||||
sq_delete(this,SQWeakRef);
|
||||
}
|
||||
@@ -149,7 +149,7 @@ bool SQGenerator::Yield(SQVM *v)
|
||||
for(SQInteger j = nvargs - 1; j >= 0; j--) {
|
||||
_vargsstack.push_back(v->_vargsstack[vargsbase+j]);
|
||||
}
|
||||
_ci._generator=NULL;
|
||||
_ci._generator=nullptr;
|
||||
for(SQInteger i=0;i<_ci._etraps;i++) {
|
||||
_etraps.push_back(v->_etraps.top());
|
||||
v->_etraps.pop_back();
|
||||
@@ -204,7 +204,7 @@ void SQArray::Extend(const SQArray *a){
|
||||
const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
|
||||
{
|
||||
SQUnsignedInteger nvars=_nlocalvarinfos;
|
||||
const SQChar *res=NULL;
|
||||
const SQChar *res=nullptr;
|
||||
if(nvars>=nseq){
|
||||
for(SQUnsignedInteger i=0;i<nvars;i++){
|
||||
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)
|
||||
|
||||
6
src/3rdparty/squirrel/squirrel/sqobject.h
vendored
6
src/3rdparty/squirrel/squirrel/sqobject.h
vendored
@@ -56,7 +56,7 @@ enum SQMetaMethod{
|
||||
|
||||
struct SQRefCounted
|
||||
{
|
||||
SQRefCounted() { _uiRef = 0; _weakref = NULL; }
|
||||
SQRefCounted() { _uiRef = 0; _weakref = nullptr; }
|
||||
virtual ~SQRefCounted();
|
||||
SQWeakRef *GetWeakRef(SQObjectType type);
|
||||
SQUnsignedInteger _uiRef;
|
||||
@@ -134,7 +134,7 @@ struct SQObjectPtr : public SQObject
|
||||
{
|
||||
SQ_OBJECT_RAWINIT()
|
||||
_type=OT_NULL;
|
||||
_unVal.pUserPointer=NULL;
|
||||
_unVal.pUserPointer=nullptr;
|
||||
}
|
||||
SQObjectPtr(const SQObjectPtr &o)
|
||||
{
|
||||
@@ -281,7 +281,7 @@ struct SQObjectPtr : public SQObject
|
||||
tOldType = _type;
|
||||
unOldVal = _unVal;
|
||||
_type = OT_NULL;
|
||||
_unVal.pUserPointer = NULL;
|
||||
_unVal.pUserPointer = nullptr;
|
||||
__Release(tOldType,unOldVal);
|
||||
}
|
||||
inline SQObjectPtr& operator=(SQInteger i)
|
||||
|
||||
44
src/3rdparty/squirrel/squirrel/sqstate.cpp
vendored
44
src/3rdparty/squirrel/squirrel/sqstate.cpp
vendored
@@ -79,12 +79,12 @@ SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
|
||||
{
|
||||
SQInteger i=0;
|
||||
SQTable *t=SQTable::Create(ss,0);
|
||||
while(funcz[i].name!=0){
|
||||
while(funcz[i].name!=nullptr){
|
||||
SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
|
||||
nc->_nparamscheck = funcz[i].nparamscheck;
|
||||
nc->_name = SQString::Create(ss,funcz[i].name);
|
||||
if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
|
||||
return NULL;
|
||||
return nullptr;
|
||||
t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
|
||||
i++;
|
||||
}
|
||||
@@ -93,15 +93,15 @@ SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
|
||||
|
||||
SQSharedState::SQSharedState()
|
||||
{
|
||||
_compilererrorhandler = NULL;
|
||||
_printfunc = NULL;
|
||||
_compilererrorhandler = nullptr;
|
||||
_printfunc = nullptr;
|
||||
_debuginfo = false;
|
||||
_notifyallexceptions = false;
|
||||
_scratchpad=NULL;
|
||||
_scratchpad=nullptr;
|
||||
_scratchpadsize=0;
|
||||
_collectable_free_processing = false;
|
||||
#ifndef NO_GARBAGE_COLLECTOR
|
||||
_gc_chain=NULL;
|
||||
_gc_chain=nullptr;
|
||||
#endif
|
||||
sq_new(_stringtable,SQStringTable);
|
||||
sq_new(_metamethods,SQObjectPtrVec);
|
||||
@@ -189,7 +189,7 @@ SQSharedState::~SQSharedState()
|
||||
_refs_table.Finalize();
|
||||
#ifndef NO_GARBAGE_COLLECTOR
|
||||
SQCollectable *t = _gc_chain;
|
||||
SQCollectable *nx = NULL;
|
||||
SQCollectable *nx = nullptr;
|
||||
if(t) {
|
||||
t->_uiRef++;
|
||||
while(t) {
|
||||
@@ -299,7 +299,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
|
||||
EnqueueMarkObject(_instance_default_delegate,queue);
|
||||
EnqueueMarkObject(_weakref_default_delegate,queue);
|
||||
|
||||
SQCollectable *tchain=NULL;
|
||||
SQCollectable *tchain=nullptr;
|
||||
|
||||
while (!queue.IsEmpty()) {
|
||||
SQCollectable *q = queue.Pop();
|
||||
@@ -309,7 +309,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
|
||||
}
|
||||
|
||||
SQCollectable *t = _gc_chain;
|
||||
SQCollectable *nx = NULL;
|
||||
SQCollectable *nx = nullptr;
|
||||
if(t) {
|
||||
t->_uiRef++;
|
||||
while(t) {
|
||||
@@ -340,7 +340,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
|
||||
#ifndef NO_GARBAGE_COLLECTOR
|
||||
void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
|
||||
{
|
||||
c->_prev = NULL;
|
||||
c->_prev = nullptr;
|
||||
c->_next = *chain;
|
||||
if(*chain) (*chain)->_prev = c;
|
||||
*chain = c;
|
||||
@@ -352,8 +352,8 @@ void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
|
||||
else *chain = c->_next;
|
||||
if(c->_next)
|
||||
c->_next->_prev = c->_prev;
|
||||
c->_next = NULL;
|
||||
c->_prev = NULL;
|
||||
c->_next = nullptr;
|
||||
c->_prev = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -483,16 +483,16 @@ RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bo
|
||||
{
|
||||
RefNode *ref;
|
||||
mainpos = ::HashObj(obj)&(_numofslots-1);
|
||||
*prev = NULL;
|
||||
*prev = nullptr;
|
||||
for (ref = _buckets[mainpos]; ref; ) {
|
||||
if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
|
||||
break;
|
||||
*prev = ref;
|
||||
ref = ref->next;
|
||||
}
|
||||
if(ref == NULL && add) {
|
||||
if(ref == nullptr && add) {
|
||||
if(_numofslots == _slotused) {
|
||||
assert(_freelist == 0);
|
||||
assert(_freelist == nullptr);
|
||||
Resize(_numofslots*2);
|
||||
mainpos = ::HashObj(obj)&(_numofslots-1);
|
||||
}
|
||||
@@ -510,16 +510,16 @@ void RefTable::AllocNodes(SQUnsignedInteger size)
|
||||
RefNode *temp = nodes;
|
||||
SQUnsignedInteger n;
|
||||
for(n = 0; n < size - 1; n++) {
|
||||
bucks[n] = NULL;
|
||||
bucks[n] = nullptr;
|
||||
temp->refs = 0;
|
||||
new (&temp->obj) SQObjectPtr;
|
||||
temp->next = temp+1;
|
||||
temp++;
|
||||
}
|
||||
bucks[n] = NULL;
|
||||
bucks[n] = nullptr;
|
||||
temp->refs = 0;
|
||||
new (&temp->obj) SQObjectPtr;
|
||||
temp->next = NULL;
|
||||
temp->next = nullptr;
|
||||
_freelist = nodes;
|
||||
_nodes = nodes;
|
||||
_buckets = bucks;
|
||||
@@ -543,7 +543,7 @@ SQStringTable::SQStringTable()
|
||||
SQStringTable::~SQStringTable()
|
||||
{
|
||||
SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
|
||||
_strings = NULL;
|
||||
_strings = nullptr;
|
||||
}
|
||||
|
||||
void SQStringTable::AllocNodes(SQInteger size)
|
||||
@@ -580,8 +580,8 @@ SQString::SQString(const SQChar *news, SQInteger len)
|
||||
_val[len] = '\0';
|
||||
_len = len;
|
||||
_hash = ::_hashstr(news,(size_t)len);
|
||||
_next = NULL;
|
||||
_sharedstate = NULL;
|
||||
_next = nullptr;
|
||||
_sharedstate = nullptr;
|
||||
}
|
||||
|
||||
void SQStringTable::Resize(SQInteger size)
|
||||
@@ -605,7 +605,7 @@ void SQStringTable::Resize(SQInteger size)
|
||||
void SQStringTable::Remove(SQString *bs)
|
||||
{
|
||||
SQString *s;
|
||||
SQString *prev=NULL;
|
||||
SQString *prev=nullptr;
|
||||
SQHash h = bs->_hash&(_numofslots - 1);
|
||||
|
||||
for (s = _strings[h]; s; ){
|
||||
|
||||
12
src/3rdparty/squirrel/squirrel/sqtable.cpp
vendored
12
src/3rdparty/squirrel/squirrel/sqtable.cpp
vendored
@@ -18,7 +18,7 @@ SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
|
||||
while(nInitialSize>pow2size)pow2size=pow2size<<1;
|
||||
AllocNodes(pow2size);
|
||||
_usednodes = 0;
|
||||
_delegate = NULL;
|
||||
_delegate = nullptr;
|
||||
INIT_CHAIN();
|
||||
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
|
||||
}
|
||||
@@ -39,7 +39,7 @@ void SQTable::AllocNodes(SQInteger nSize)
|
||||
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
|
||||
for(SQInteger i=0;i<nSize;i++){
|
||||
new (&nodes[i]) _HashNode;
|
||||
nodes[i].next=NULL;
|
||||
nodes[i].next=nullptr;
|
||||
}
|
||||
_numofnodes=nSize;
|
||||
_nodes=nodes;
|
||||
@@ -120,7 +120,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
|
||||
if (mp > n && (othern = &_nodes[mph]) != mp){
|
||||
/* yes; move colliding node into free position */
|
||||
while (othern->next != mp){
|
||||
assert(othern->next != NULL);
|
||||
assert(othern->next != nullptr);
|
||||
othern = othern->next; /* find previous */
|
||||
}
|
||||
othern->next = n; /* redo the chain with `n' in place of `mp' */
|
||||
@@ -129,7 +129,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
|
||||
n->next = mp->next;
|
||||
mp->key = _null_;
|
||||
mp->val = _null_;
|
||||
mp->next = NULL; /* now `mp' is free */
|
||||
mp->next = nullptr; /* now `mp' is free */
|
||||
}
|
||||
else{
|
||||
/* new node will go into free position */
|
||||
@@ -141,7 +141,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
|
||||
mp->key = key;
|
||||
|
||||
for (;;) { /* correct `firstfree' */
|
||||
if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
|
||||
if (type(_firstfree->key) == OT_NULL && _firstfree->next == nullptr) {
|
||||
mp->val = val;
|
||||
_usednodes++;
|
||||
return true; /* OK; table still has a free place */
|
||||
@@ -190,7 +190,7 @@ void SQTable::_ClearNodes()
|
||||
void SQTable::Finalize()
|
||||
{
|
||||
_ClearNodes();
|
||||
SetDelegate(NULL);
|
||||
SetDelegate(nullptr);
|
||||
}
|
||||
|
||||
void SQTable::Clear()
|
||||
|
||||
8
src/3rdparty/squirrel/squirrel/sqtable.h
vendored
8
src/3rdparty/squirrel/squirrel/sqtable.h
vendored
@@ -27,7 +27,7 @@ struct SQTable : public SQDelegable
|
||||
private:
|
||||
struct _HashNode
|
||||
{
|
||||
_HashNode() { next = NULL; }
|
||||
_HashNode() { next = nullptr; }
|
||||
SQObjectPtr val;
|
||||
SQObjectPtr key;
|
||||
_HashNode *next;
|
||||
@@ -47,14 +47,14 @@ public:
|
||||
{
|
||||
SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
|
||||
new (newtable) SQTable(ss, nInitialSize);
|
||||
newtable->_delegate = NULL;
|
||||
newtable->_delegate = nullptr;
|
||||
return newtable;
|
||||
}
|
||||
void Finalize() override;
|
||||
SQTable *Clone();
|
||||
~SQTable()
|
||||
{
|
||||
SetDelegate(NULL);
|
||||
SetDelegate(nullptr);
|
||||
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
|
||||
for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
|
||||
SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
|
||||
@@ -70,7 +70,7 @@ public:
|
||||
return n;
|
||||
}
|
||||
}while((n = n->next));
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
bool Get(const SQObjectPtr &key,SQObjectPtr &val);
|
||||
void Remove(const SQObjectPtr &key);
|
||||
|
||||
6
src/3rdparty/squirrel/squirrel/squserdata.h
vendored
6
src/3rdparty/squirrel/squirrel/squserdata.h
vendored
@@ -4,12 +4,12 @@
|
||||
|
||||
struct SQUserData : SQDelegable
|
||||
{
|
||||
SQUserData(SQSharedState *ss, SQInteger size){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); _size = size; _typetag = 0;
|
||||
SQUserData(SQSharedState *ss, SQInteger size){ _delegate = nullptr; _hook = nullptr; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); _size = size; _typetag = nullptr;
|
||||
}
|
||||
~SQUserData()
|
||||
{
|
||||
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
|
||||
SetDelegate(NULL);
|
||||
SetDelegate(nullptr);
|
||||
}
|
||||
static SQUserData* Create(SQSharedState *ss, SQInteger size)
|
||||
{
|
||||
@@ -19,7 +19,7 @@ struct SQUserData : SQDelegable
|
||||
}
|
||||
#ifndef NO_GARBAGE_COLLECTOR
|
||||
void EnqueueMarkObjectForChildren(SQGCMarkerQueue &queue);
|
||||
void Finalize(){SetDelegate(NULL);}
|
||||
void Finalize(){SetDelegate(nullptr);}
|
||||
#endif
|
||||
void Release() {
|
||||
if (_hook) _hook(_val,_size);
|
||||
|
||||
2
src/3rdparty/squirrel/squirrel/squtils.h
vendored
2
src/3rdparty/squirrel/squirrel/squtils.h
vendored
@@ -18,7 +18,7 @@ template<typename T> class sqvector
|
||||
public:
|
||||
sqvector()
|
||||
{
|
||||
_vals = NULL;
|
||||
_vals = nullptr;
|
||||
_size = 0;
|
||||
_allocated = 0;
|
||||
}
|
||||
|
||||
30
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
30
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
@@ -33,7 +33,7 @@ void SQVM::ClearStack(SQInteger last_top)
|
||||
tOldType = o._type;
|
||||
unOldVal = o._unVal;
|
||||
o._type = OT_NULL;
|
||||
o._unVal.pUserPointer = NULL;
|
||||
o._unVal.pUserPointer = nullptr;
|
||||
__Release(tOldType,unOldVal);
|
||||
}
|
||||
}
|
||||
@@ -107,7 +107,7 @@ SQVM::SQVM(SQSharedState *ss)
|
||||
_suspended_target=-1;
|
||||
_suspended_root = SQFalse;
|
||||
_suspended_traps=0;
|
||||
_foreignptr=NULL;
|
||||
_foreignptr=nullptr;
|
||||
_nnativecalls=0;
|
||||
_lasterror = _null_;
|
||||
_errorhandler = _null_;
|
||||
@@ -115,12 +115,12 @@ SQVM::SQVM(SQSharedState *ss)
|
||||
_can_suspend = false;
|
||||
_in_stackoverflow = false;
|
||||
_ops_till_suspend = 0;
|
||||
_callsstack = NULL;
|
||||
_callsstack = nullptr;
|
||||
_callsstacksize = 0;
|
||||
_alloccallsstacksize = 0;
|
||||
_top = 0;
|
||||
_stackbase = 0;
|
||||
ci = NULL;
|
||||
ci = nullptr;
|
||||
INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
|
||||
}
|
||||
|
||||
@@ -379,7 +379,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege
|
||||
|
||||
if (!tailcall) {
|
||||
CallInfo lc = {};
|
||||
lc._generator = NULL;
|
||||
lc._generator = nullptr;
|
||||
lc._etraps = 0;
|
||||
lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
|
||||
lc._target = (SQInt32) target;
|
||||
@@ -437,7 +437,7 @@ bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
|
||||
|
||||
while (last_top > oldstackbase) _stack._vals[last_top--].Null();
|
||||
assert(oldstackbase >= _stackbase);
|
||||
return broot?true:false;
|
||||
return broot != 0;
|
||||
}
|
||||
|
||||
#define _RET_ON_FAIL(exp) { if(!exp) return false; }
|
||||
@@ -557,7 +557,7 @@ bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
|
||||
}
|
||||
break;
|
||||
case OT_NULL:
|
||||
_table(o1)->SetDelegate(NULL);
|
||||
_table(o1)->SetDelegate(nullptr);
|
||||
break;
|
||||
default:
|
||||
Raise_Error("using '%s' as delegate", GetTypeName(o2));
|
||||
@@ -627,7 +627,7 @@ bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
|
||||
|
||||
bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
|
||||
{
|
||||
SQClass *base = NULL;
|
||||
SQClass *base = nullptr;
|
||||
SQObjectPtr attrs;
|
||||
if(baseclass != -1) {
|
||||
if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error("trying to inherit from a %s",GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
|
||||
@@ -653,7 +653,7 @@ bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes
|
||||
bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
|
||||
{
|
||||
if(type(o1) == type(o2)) {
|
||||
res = ((_rawval(o1) == _rawval(o2)?true:false));
|
||||
res = ((_rawval(o1) == _rawval(o2)));
|
||||
}
|
||||
else {
|
||||
if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
|
||||
@@ -708,7 +708,7 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn
|
||||
temp_reg = closure;
|
||||
if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) {
|
||||
//call the handler if there are no calls in the stack, if not relies on the previous node
|
||||
if(ci == NULL) CallErrorHandler(_lasterror);
|
||||
if(ci == nullptr) CallErrorHandler(_lasterror);
|
||||
return false;
|
||||
}
|
||||
if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
|
||||
@@ -1028,7 +1028,7 @@ common_call:
|
||||
case _OP_THROW: Raise_Error(TARGET); SQ_THROW();
|
||||
case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
|
||||
case _OP_NEWSLOTA:
|
||||
bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
|
||||
bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG) != 0;
|
||||
if(type(STK(arg1)) == OT_CLASS) {
|
||||
if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
|
||||
Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
|
||||
@@ -1160,7 +1160,7 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb
|
||||
_top = stackbase + nargs;
|
||||
CallInfo lci = {};
|
||||
lci._closure = nclosure;
|
||||
lci._generator = NULL;
|
||||
lci._generator = nullptr;
|
||||
lci._etraps = 0;
|
||||
lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
|
||||
lci._ncalls = 1;
|
||||
@@ -1471,9 +1471,7 @@ bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr
|
||||
|
||||
bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror,SQBool can_suspend)
|
||||
{
|
||||
#ifdef WITH_ASSERT
|
||||
SQInteger prevstackbase = _stackbase;
|
||||
#endif
|
||||
[[maybe_unused]] SQInteger prevstackbase = _stackbase;
|
||||
switch(type(closure)) {
|
||||
case OT_CLOSURE: {
|
||||
assert(!can_suspend || this->_can_suspend);
|
||||
@@ -1504,11 +1502,9 @@ bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObj
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#ifdef WITH_ASSERT
|
||||
if(!_suspended) {
|
||||
assert(_stackbase == prevstackbase);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -311,6 +311,8 @@ add_files(
|
||||
rail_gui.h
|
||||
rail_map.h
|
||||
rail_type.h
|
||||
random_access_file.cpp
|
||||
random_access_file_type.h
|
||||
rev.h
|
||||
road.cpp
|
||||
road.h
|
||||
@@ -338,6 +340,8 @@ add_files(
|
||||
settings_gui.cpp
|
||||
settings_gui.h
|
||||
settings_internal.h
|
||||
settings_table.h
|
||||
settings_table.cpp
|
||||
settings_type.h
|
||||
ship.h
|
||||
ship_cmd.cpp
|
||||
@@ -469,6 +473,7 @@ add_files(
|
||||
viewport_type.h
|
||||
void_cmd.cpp
|
||||
void_map.h
|
||||
walltime_func.h
|
||||
water.h
|
||||
water_cmd.cpp
|
||||
water_map.h
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
cur_company.Restore();
|
||||
|
||||
InvalidateWindowData(WC_AI_DEBUG, 0, -1);
|
||||
DeleteWindowById(WC_AI_SETTINGS, company);
|
||||
CloseWindowById(WC_AI_SETTINGS, company);
|
||||
}
|
||||
|
||||
/* static */ void AI::Pause(CompanyID company)
|
||||
@@ -207,7 +207,7 @@
|
||||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
if (_settings_game.ai_config[c] != nullptr && _settings_game.ai_config[c]->HasScript()) {
|
||||
if (!_settings_game.ai_config[c]->ResetInfo(true)) {
|
||||
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
|
||||
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
|
||||
_settings_game.ai_config[c]->Change(nullptr);
|
||||
if (Company::IsValidAiID(c)) {
|
||||
/* The code belonging to an already running AI was deleted. We can only do
|
||||
@@ -224,7 +224,7 @@
|
||||
}
|
||||
if (_settings_newgame.ai_config[c] != nullptr && _settings_newgame.ai_config[c]->HasScript()) {
|
||||
if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
|
||||
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
|
||||
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
|
||||
_settings_newgame.ai_config[c]->Change(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ struct AIListWindow : public Window {
|
||||
}
|
||||
InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI);
|
||||
InvalidateWindowClassesData(WC_AI_SETTINGS);
|
||||
DeleteWindowByClass(WC_QUERY_STRING);
|
||||
CloseWindowByClass(WC_QUERY_STRING);
|
||||
InvalidateWindowClassesData(WC_TEXTFILE);
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ struct AIListWindow : public Window {
|
||||
this->SetDirty();
|
||||
if (click_count > 1) {
|
||||
this->ChangeAI();
|
||||
delete this;
|
||||
this->Close();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -206,12 +206,12 @@ struct AIListWindow : public Window {
|
||||
|
||||
case WID_AIL_ACCEPT: {
|
||||
this->ChangeAI();
|
||||
delete this;
|
||||
this->Close();
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_AIL_CANCEL:
|
||||
delete this;
|
||||
this->Close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +229,7 @@ struct AIListWindow : public Window {
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
if (_game_mode == GM_NORMAL && Company::IsValidID(this->slot)) {
|
||||
delete this;
|
||||
this->Close();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ static WindowDesc _ai_list_desc(
|
||||
*/
|
||||
static void ShowAIListWindow(CompanyID slot)
|
||||
{
|
||||
DeleteWindowByClass(WC_AI_LIST);
|
||||
CloseWindowByClass(WC_AI_LIST);
|
||||
new AIListWindow(&_ai_list_desc, slot);
|
||||
}
|
||||
|
||||
@@ -446,7 +446,7 @@ struct AISettingsWindow : public Window {
|
||||
if (!this->IsEditableItem(config_item)) return;
|
||||
|
||||
if (this->clicked_row != num) {
|
||||
DeleteChildWindows(WC_QUERY_STRING);
|
||||
this->CloseChildWindows(WC_QUERY_STRING);
|
||||
HideDropDownMenu(this);
|
||||
this->clicked_row = num;
|
||||
this->clicked_dropdown = false;
|
||||
@@ -520,7 +520,7 @@ struct AISettingsWindow : public Window {
|
||||
}
|
||||
|
||||
case WID_AIS_ACCEPT:
|
||||
delete this;
|
||||
this->Close();
|
||||
break;
|
||||
|
||||
case WID_AIS_RESET:
|
||||
@@ -586,7 +586,7 @@ struct AISettingsWindow : public Window {
|
||||
{
|
||||
this->RebuildVisibleSettings();
|
||||
HideDropDownMenu(this);
|
||||
DeleteChildWindows(WC_QUERY_STRING);
|
||||
this->CloseChildWindows(WC_QUERY_STRING);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -630,8 +630,8 @@ static WindowDesc _ai_settings_desc(
|
||||
*/
|
||||
static void ShowAISettingsWindow(CompanyID slot)
|
||||
{
|
||||
DeleteWindowByClass(WC_AI_LIST);
|
||||
DeleteWindowByClass(WC_AI_SETTINGS);
|
||||
CloseWindowByClass(WC_AI_LIST);
|
||||
CloseWindowByClass(WC_AI_SETTINGS);
|
||||
new AISettingsWindow(&_ai_settings_desc, slot);
|
||||
}
|
||||
|
||||
@@ -657,7 +657,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
|
||||
{
|
||||
const char *textfile = GetConfig(slot)->GetTextfile(file_type, slot);
|
||||
if (textfile == nullptr) {
|
||||
delete this;
|
||||
this->Close();
|
||||
} else {
|
||||
this->LoadTextfile(textfile, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR);
|
||||
}
|
||||
@@ -671,7 +671,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
|
||||
*/
|
||||
void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot)
|
||||
{
|
||||
DeleteWindowById(WC_TEXTFILE, file_type);
|
||||
CloseWindowById(WC_TEXTFILE, file_type);
|
||||
new ScriptTextfileWindow(file_type, slot);
|
||||
}
|
||||
|
||||
@@ -737,10 +737,11 @@ struct AIConfigWindow : public Window {
|
||||
this->OnInvalidateData(0);
|
||||
}
|
||||
|
||||
~AIConfigWindow()
|
||||
void Close() override
|
||||
{
|
||||
DeleteWindowByClass(WC_AI_LIST);
|
||||
DeleteWindowByClass(WC_AI_SETTINGS);
|
||||
CloseWindowByClass(WC_AI_LIST);
|
||||
CloseWindowByClass(WC_AI_SETTINGS);
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
@@ -923,7 +924,7 @@ struct AIConfigWindow : public Window {
|
||||
break;
|
||||
|
||||
case WID_AIC_CLOSE:
|
||||
delete this;
|
||||
this->Close();
|
||||
break;
|
||||
|
||||
case WID_AIC_CONTENT_DOWNLOAD:
|
||||
@@ -965,7 +966,7 @@ struct AIConfigWindow : public Window {
|
||||
/** Open the AI config window. */
|
||||
void ShowAIConfigWindow()
|
||||
{
|
||||
DeleteWindowByClass(WC_GAME_OPTIONS);
|
||||
CloseWindowByClass(WC_GAME_OPTIONS);
|
||||
new AIConfigWindow();
|
||||
}
|
||||
|
||||
@@ -1259,7 +1260,7 @@ struct AIDebugWindow : public Window {
|
||||
this->highlight_row = -1; // The highlight of one AI make little sense for another AI.
|
||||
|
||||
/* Close AI settings window to prevent confusion */
|
||||
DeleteWindowByClass(WC_AI_SETTINGS);
|
||||
CloseWindowByClass(WC_AI_SETTINGS);
|
||||
|
||||
this->InvalidateData(-1);
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
*/
|
||||
static bool CheckAPIVersion(const char *api_version)
|
||||
{
|
||||
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "1.12" };
|
||||
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12" };
|
||||
return versions.find(api_version) != versions.end();
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
{
|
||||
/* Get the AIInfo */
|
||||
SQUserPointer instance = nullptr;
|
||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
|
||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, nullptr)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
|
||||
AIInfo *info = (AIInfo *)instance;
|
||||
|
||||
SQInteger res = ScriptInfo::Constructor(vm, info);
|
||||
@@ -89,7 +89,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
if (info->engine->MethodExists(*info->SQ_instance, "GetAPIVersion")) {
|
||||
if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR;
|
||||
if (!CheckAPIVersion(info->api_version)) {
|
||||
DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
|
||||
Debug(script, 1, "Loading info.nut from ({}.{}): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
|
||||
return SQ_ERROR;
|
||||
}
|
||||
} else {
|
||||
@@ -107,7 +107,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
|
||||
{
|
||||
/* Get the AIInfo */
|
||||
SQUserPointer instance;
|
||||
sq_getinstanceup(vm, 2, &instance, 0);
|
||||
sq_getinstanceup(vm, 2, &instance, nullptr);
|
||||
AIInfo *info = (AIInfo *)instance;
|
||||
info->api_version = nullptr;
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ AIInfo *AIScannerInfo::SelectRandomAI() const
|
||||
}
|
||||
|
||||
if (num_random_ais == 0) {
|
||||
DEBUG(script, 0, "No suitable AI found, loading 'dummy' AI.");
|
||||
Debug(script, 0, "No suitable AI found, loading 'dummy' AI.");
|
||||
return this->info_dummy;
|
||||
}
|
||||
|
||||
|
||||
@@ -1025,7 +1025,7 @@ static bool AircraftController(Aircraft *v)
|
||||
if (count == 0) return false;
|
||||
|
||||
/* If the plane will be a few subpixels away from the destination after
|
||||
* this movement loop, start nudging him towards the exact position for
|
||||
* this movement loop, start nudging it towards the exact position for
|
||||
* the whole loop. Otherwise, heavily depending on the speed of the plane,
|
||||
* it is possible we totally overshoot the target, causing the plane to
|
||||
* make a loop, and trying again, and again, and again .. */
|
||||
@@ -1786,7 +1786,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
|
||||
{
|
||||
/* error handling */
|
||||
if (v->pos >= apc->nofelements) {
|
||||
DEBUG(misc, 0, "[Ap] position %d is not valid for current airport. Max position is %d", v->pos, apc->nofelements-1);
|
||||
Debug(misc, 0, "[Ap] position {} is not valid for current airport. Max position is {}", v->pos, apc->nofelements-1);
|
||||
assert(v->pos < apc->nofelements);
|
||||
}
|
||||
|
||||
@@ -1825,7 +1825,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
|
||||
current = current->next;
|
||||
} while (current != nullptr);
|
||||
|
||||
DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d) for vehicle %d", v->pos, v->state, v->index);
|
||||
Debug(misc, 0, "[Ap] cannot move further on Airport! (pos {} state {}) for vehicle {}", v->pos, v->state, v->index);
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,11 +78,12 @@ struct BuildAirToolbarWindow : Window {
|
||||
this->last_user_action = WIDGET_LIST_END;
|
||||
}
|
||||
|
||||
~BuildAirToolbarWindow()
|
||||
void Close() override
|
||||
{
|
||||
if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
|
||||
if (this->IsWidgetLowered(WID_AT_AIRPORT)) SetViewportCatchmentStation(nullptr, true);
|
||||
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
|
||||
if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false);
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +100,7 @@ struct BuildAirToolbarWindow : Window {
|
||||
WID_AT_AIRPORT,
|
||||
WIDGET_LIST_END);
|
||||
if (!can_build) {
|
||||
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
|
||||
CloseWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
|
||||
|
||||
/* Show in the tooltip why this button is disabled. */
|
||||
this->GetWidget<NWidgetCore>(WID_AT_AIRPORT)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE);
|
||||
@@ -173,8 +174,8 @@ struct BuildAirToolbarWindow : Window {
|
||||
MoveAllHiddenWindowsBackToScreen();
|
||||
this->RaiseButtons();
|
||||
if (!ConfirmationWindowShown()) {
|
||||
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
|
||||
DeleteWindowById(WC_SELECT_STATION, 0);
|
||||
CloseWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
|
||||
CloseWindowById(WC_SELECT_STATION, 0);
|
||||
}
|
||||
ResetObjectToPlace();
|
||||
}
|
||||
@@ -234,7 +235,7 @@ Window *ShowBuildAirToolbar()
|
||||
{
|
||||
if (!Company::IsValidID(_local_company)) return nullptr;
|
||||
|
||||
DeleteToolbarLinkedWindows();
|
||||
CloseToolbarLinkedWindows();
|
||||
return AllocateWindowDescFront<BuildAirToolbarWindow>(&_air_toolbar_desc, TRANSPORT_AIR);
|
||||
}
|
||||
|
||||
@@ -293,9 +294,10 @@ public:
|
||||
if (selectFirstAirport) this->SelectFirstAvailableAirport(true);
|
||||
}
|
||||
|
||||
virtual ~BuildAirportWindow()
|
||||
void Close() override
|
||||
{
|
||||
DeleteWindowById(WC_SELECT_STATION, 0);
|
||||
CloseWindowById(WC_SELECT_STATION, 0);
|
||||
this->PickerWindowBase::Close();
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
@@ -503,7 +505,7 @@ public:
|
||||
break;
|
||||
|
||||
case WID_AP_AIRPORT_LIST: {
|
||||
int num_clicked = this->vscroll->GetPosition() + (pt.y - this->nested_array[widget]->pos_y) / this->line_height;
|
||||
int num_clicked = this->vscroll->GetPosition() + (pt.y - this->GetWidget<NWidgetBase>(widget)->pos_y) / this->line_height;
|
||||
if (num_clicked >= this->vscroll->GetCount()) break;
|
||||
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(num_clicked);
|
||||
if (as->IsAvailable()) this->SelectOtherAirport(num_clicked);
|
||||
|
||||
@@ -207,6 +207,7 @@ static int GetIncompatibleRefitOrderIdForAutoreplace(const Vehicle *v, EngineID
|
||||
const Vehicle *u = (v->type == VEH_TRAIN) ? v->First() : v;
|
||||
|
||||
const OrderList *orders = u->orders.list;
|
||||
if (orders == nullptr) return -1;
|
||||
for (VehicleOrderID i = 0; i < orders->GetNumOrders(); i++) {
|
||||
o = orders->GetOrderAt(i);
|
||||
if (!o->IsRefit()) continue;
|
||||
@@ -596,8 +597,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
|
||||
|
||||
/* Sell wagon */
|
||||
CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
|
||||
(void)ret; // assert only
|
||||
[[maybe_unused]] CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
|
||||
assert(ret.Succeeded());
|
||||
new_vehs[i] = nullptr;
|
||||
|
||||
@@ -614,6 +614,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
/* Success ! */
|
||||
if ((flags & DC_EXEC) != 0 && new_head != old_head) {
|
||||
*chain = new_head;
|
||||
AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index));
|
||||
}
|
||||
|
||||
/* Transfer cargo of old vehicles and sell them */
|
||||
@@ -631,10 +632,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
cost.AddCost(DoCommand(0, w->index, 0, flags | DC_AUTOREPLACE, GetCmdSellVeh(w)));
|
||||
if ((flags & DC_EXEC) != 0) {
|
||||
old_vehs[i] = nullptr;
|
||||
if (i == 0) {
|
||||
AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index));
|
||||
old_head = nullptr;
|
||||
}
|
||||
if (i == 0) old_head = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,8 +650,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
assert(Train::From(old_head)->GetNextUnit() == nullptr);
|
||||
|
||||
for (int i = num_units - 1; i > 0; i--) {
|
||||
CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
|
||||
(void)ret; // assert only
|
||||
[[maybe_unused]] CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
|
||||
assert(ret.Succeeded());
|
||||
}
|
||||
}
|
||||
@@ -717,7 +714,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
Vehicle *v = Vehicle::GetIfValid(p1);
|
||||
if (v == nullptr) return CMD_ERROR;
|
||||
@@ -810,7 +807,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
Company *c = Company::GetIfValid(_current_company);
|
||||
if (c == nullptr) return CMD_ERROR;
|
||||
|
||||
@@ -382,11 +382,14 @@ public:
|
||||
const Group *g = Group::GetIfValid(this->sel_group);
|
||||
if (g != nullptr) {
|
||||
remove_wagon = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
|
||||
SetDParam(0, STR_GROUP_NAME);
|
||||
SetDParam(1, sel_group);
|
||||
} else {
|
||||
const Company *c = Company::Get(_local_company);
|
||||
remove_wagon = c->settings.renew_keep_length;
|
||||
SetDParam(0, STR_GROUP_DEFAULT_TRAINS + this->window_number);
|
||||
}
|
||||
SetDParam(0, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
|
||||
SetDParam(2, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -544,7 +547,7 @@ public:
|
||||
DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG);
|
||||
} else {
|
||||
// toggle renew_keep_length
|
||||
DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING);
|
||||
DoCommandP(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING, nullptr, "company.renew_keep_length");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -645,6 +648,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override
|
||||
{
|
||||
if (widget != WID_RV_TRAIN_WAGONREMOVE_TOGGLE) return false;
|
||||
|
||||
if (Group::IsValidID(this->sel_group)) {
|
||||
uint64 params[1];
|
||||
params[0] = STR_REPLACE_REMOVE_WAGON_HELP;
|
||||
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_GROUP_HELP, 1, params, close_cond);
|
||||
} else {
|
||||
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_HELP, 0, nullptr, close_cond);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnResize() override
|
||||
{
|
||||
this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX);
|
||||
@@ -844,7 +861,7 @@ static WindowDesc _replace_vehicle_desc(
|
||||
*/
|
||||
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
|
||||
{
|
||||
DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype);
|
||||
CloseWindowById(WC_REPLACE_VEHICLE, vehicletype);
|
||||
WindowDesc *desc;
|
||||
switch (vehicletype) {
|
||||
case VEH_TRAIN: desc = &_replace_rail_vehicle_desc; break;
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#define fetch_metadata(name) \
|
||||
item = metadata->GetItem(name, false); \
|
||||
if (item == nullptr || !item->value.has_value() || item->value->empty()) { \
|
||||
DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: %s field missing.", name); \
|
||||
DEBUG(grf, 0, " Is %s readable for the user running OpenTTD?", full_filename); \
|
||||
Debug(grf, 0, "Base " SET_TYPE "set detail loading: {} field missing.", name); \
|
||||
Debug(grf, 0, " Is {} readable for the user running OpenTTD?", full_filename); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
/* Find the filename first. */
|
||||
item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], false);
|
||||
if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
|
||||
DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
|
||||
Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
/* Then find the MD5 checksum */
|
||||
item = md5s->GetItem(filename, false);
|
||||
if (item == nullptr || !item->value.has_value()) {
|
||||
DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename, full_filename);
|
||||
Debug(grf, 0, "No MD5 checksum specified for: {} (in {})", filename, full_filename);
|
||||
return false;
|
||||
}
|
||||
const char *c = item->value->c_str();
|
||||
@@ -105,7 +105,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
} else if ('A' <= *c && *c <= 'F') {
|
||||
j = *c - 'A' + 10;
|
||||
} else {
|
||||
DEBUG(grf, 0, "Malformed MD5 checksum specified for: %s (in %s)", filename, full_filename);
|
||||
Debug(grf, 0, "Malformed MD5 checksum specified for: {} (in {})", filename, full_filename);
|
||||
return false;
|
||||
}
|
||||
if (i % 2 == 0) {
|
||||
@@ -119,7 +119,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
item = origin->GetItem(filename, false);
|
||||
if (item == nullptr) item = origin->GetItem("default", false);
|
||||
if (item == nullptr || !item->value.has_value()) {
|
||||
DEBUG(grf, 1, "No origin warning message specified for: %s", filename);
|
||||
Debug(grf, 1, "No origin warning message specified for: {}", filename);
|
||||
file->missing_warning = stredup("");
|
||||
} else {
|
||||
file->missing_warning = stredup(item->value->c_str());
|
||||
@@ -136,12 +136,12 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
||||
break;
|
||||
|
||||
case MD5File::CR_MISMATCH:
|
||||
DEBUG(grf, 1, "MD5 checksum mismatch for: %s (in %s)", filename, full_filename);
|
||||
Debug(grf, 1, "MD5 checksum mismatch for: {} (in {})", filename, full_filename);
|
||||
this->found_files++;
|
||||
break;
|
||||
|
||||
case MD5File::CR_NO_FILE:
|
||||
DEBUG(grf, 1, "The file %s specified in %s is missing", filename, full_filename);
|
||||
Debug(grf, 1, "The file {} specified in {} is missing", filename, full_filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ template <class Tbase_set>
|
||||
bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename)
|
||||
{
|
||||
bool ret = false;
|
||||
DEBUG(grf, 1, "Checking %s for base " SET_TYPE " set", filename.c_str());
|
||||
Debug(grf, 1, "Checking {} for base " SET_TYPE " set", filename);
|
||||
|
||||
Tbase_set *set = new Tbase_set();
|
||||
IniFile *ini = new IniFile();
|
||||
@@ -179,7 +179,7 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
||||
/* The more complete set takes precedence over the version number. */
|
||||
if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
|
||||
duplicate->valid_files > set->valid_files) {
|
||||
DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate, %s)", set->name.c_str(), set->version,
|
||||
Debug(grf, 1, "Not adding {} ({}) as base " SET_TYPE " set (duplicate, {})", set->name, set->version,
|
||||
duplicate->valid_files > set->valid_files ? "less valid files" : "lower version");
|
||||
set->next = BaseMedia<Tbase_set>::duplicate_sets;
|
||||
BaseMedia<Tbase_set>::duplicate_sets = set;
|
||||
@@ -195,7 +195,7 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
||||
* version number until a new game is started which isn't a big problem */
|
||||
if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set;
|
||||
|
||||
DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate, %s)", duplicate->name.c_str(), duplicate->version,
|
||||
Debug(grf, 1, "Removing {} ({}) as base " SET_TYPE " set (duplicate, {})", duplicate->name, duplicate->version,
|
||||
duplicate->valid_files < set->valid_files ? "less valid files" : "lower version");
|
||||
duplicate->next = BaseMedia<Tbase_set>::duplicate_sets;
|
||||
BaseMedia<Tbase_set>::duplicate_sets = duplicate;
|
||||
@@ -209,7 +209,7 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
|
||||
ret = true;
|
||||
}
|
||||
if (ret) {
|
||||
DEBUG(grf, 1, "Adding %s (%i) as base " SET_TYPE " set", set->name.c_str(), set->version);
|
||||
Debug(grf, 1, "Adding {} ({}) as base " SET_TYPE " set", set->name, set->version);
|
||||
}
|
||||
} else {
|
||||
delete set;
|
||||
|
||||
@@ -307,7 +307,7 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height,
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('%d')", pal);
|
||||
Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
|
||||
}
|
||||
|
||||
void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
|
||||
|
||||
@@ -155,6 +155,7 @@ bmno_full_transparency:
|
||||
|
||||
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
|
||||
if (src->a == 0) {
|
||||
/* Complete transparency. */
|
||||
} else if (src->a == 255) {
|
||||
*anim = *(const uint16*) src_mv;
|
||||
*dst = (src_mv->m >= PALETTE_ANIM_START) ? AdjustBrightneSSE(LookupColourInPalette(src_mv->m), src_mv->v) : *src;
|
||||
@@ -197,7 +198,7 @@ bmno_full_transparency:
|
||||
m_colour = r == 0 ? m_colour : cmap; \
|
||||
m_colour = m != 0 ? m_colour : srcm; \
|
||||
}
|
||||
#ifdef _SQ64
|
||||
#ifdef POINTER_IS_64BIT
|
||||
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
|
||||
uint64 dsts;
|
||||
if (animated) dsts = _mm_cvtsi128_si64(dstABCD);
|
||||
@@ -379,7 +380,7 @@ bm_normal:
|
||||
else Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, true>(bp, zoom);
|
||||
}
|
||||
} else {
|
||||
#ifdef _SQ64
|
||||
#ifdef POINTER_IS_64BIT
|
||||
if (sprite_flags & SF_TRANSLUCENT) {
|
||||
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
|
||||
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
|
||||
|
||||
@@ -106,7 +106,7 @@ void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('%d')", pal);
|
||||
Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
|
||||
}
|
||||
|
||||
Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)
|
||||
|
||||
@@ -34,7 +34,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into)
|
||||
|
||||
static inline void LoadUint64(const uint64 value, __m128i &into)
|
||||
{
|
||||
#ifdef _SQ64
|
||||
#ifdef POINTER_IS_64BIT
|
||||
into = _mm_cvtsi64_si128(value);
|
||||
#else
|
||||
#if (SSE_VERSION >= 4)
|
||||
@@ -297,7 +297,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
m_colour = r == 0 ? m_colour : cmap; \
|
||||
m_colour = m != 0 ? m_colour : srcm; \
|
||||
}
|
||||
#ifdef _SQ64
|
||||
#ifdef POINTER_IS_64BIT
|
||||
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
|
||||
uint64 remapped_src = 0;
|
||||
CMOV_REMAP(c0, 0, srcs, mvX2);
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
#include <utility>
|
||||
|
||||
template <typename SetPixelT>
|
||||
void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel)
|
||||
void Blitter::DrawLineGeneric(int x1, int y1, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel)
|
||||
{
|
||||
int dy;
|
||||
int dx;
|
||||
int stepx;
|
||||
int stepy;
|
||||
|
||||
dy = (y2 - y) * 2;
|
||||
dy = (y2 - y1) * 2;
|
||||
if (dy < 0) {
|
||||
dy = -dy;
|
||||
stepy = -1;
|
||||
@@ -31,7 +31,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
stepy = 1;
|
||||
}
|
||||
|
||||
dx = (x2 - x) * 2;
|
||||
dx = (x2 - x1) * 2;
|
||||
if (dx < 0) {
|
||||
dx = -dx;
|
||||
stepx = -1;
|
||||
@@ -41,7 +41,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
|
||||
if (dx == 0 && dy == 0) {
|
||||
/* The algorithm below cannot handle this special case; make it work at least for line width 1 */
|
||||
if (x >= 0 && x < screen_width && y >= 0 && y < screen_height) set_pixel(x, y);
|
||||
if (x1 >= 0 && x1 < screen_width && y1 >= 0 && y1 < screen_height) set_pixel(x1, y1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,14 +67,14 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
int dash_count = 0;
|
||||
if (dx > dy) {
|
||||
if (stepx < 0) {
|
||||
std::swap(x, x2);
|
||||
std::swap(y, y2);
|
||||
std::swap(x1, x2);
|
||||
std::swap(y1, y2);
|
||||
stepy = -stepy;
|
||||
}
|
||||
if (x2 < 0 || x >= screen_width) return;
|
||||
if (x2 < 0 || x1 >= screen_width) return;
|
||||
|
||||
int y_low = y;
|
||||
int y_high = y;
|
||||
int y_low = y1;
|
||||
int y_high = y1;
|
||||
int frac_low = dy - frac_diff / 2;
|
||||
int frac_high = dy + frac_diff / 2;
|
||||
|
||||
@@ -87,10 +87,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
y_high += stepy;
|
||||
}
|
||||
|
||||
if (x < 0) {
|
||||
dash_count = (-x) % (dash + gap);
|
||||
if (x1 < 0) {
|
||||
dash_count = (-x1) % (dash + gap);
|
||||
auto adjust_frac = [&](int64 frac, int &y_bound) -> int {
|
||||
frac -= ((int64) dy) * ((int64) x);
|
||||
frac -= ((int64) dy) * ((int64) x1);
|
||||
if (frac >= 0) {
|
||||
int quotient = frac / dx;
|
||||
int remainder = frac % dx;
|
||||
@@ -101,17 +101,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
};
|
||||
frac_low = adjust_frac(frac_low, y_low);
|
||||
frac_high = adjust_frac(frac_high, y_high);
|
||||
x = 0;
|
||||
x1 = 0;
|
||||
}
|
||||
x2++;
|
||||
if (x2 > screen_width) {
|
||||
x2 = screen_width;
|
||||
}
|
||||
|
||||
while (x != x2) {
|
||||
while (x1 != x2) {
|
||||
if (dash_count < dash) {
|
||||
for (int y = y_low; y != y_high; y += stepy) {
|
||||
if (y >= 0 && y < screen_height) set_pixel(x, y);
|
||||
if (y >= 0 && y < screen_height) set_pixel(x1, y);
|
||||
}
|
||||
}
|
||||
if (frac_low >= 0) {
|
||||
@@ -122,21 +122,21 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
y_high += stepy;
|
||||
frac_high -= dx;
|
||||
}
|
||||
x++;
|
||||
x1++;
|
||||
frac_low += dy;
|
||||
frac_high += dy;
|
||||
if (++dash_count >= dash + gap) dash_count = 0;
|
||||
}
|
||||
} else {
|
||||
if (stepy < 0) {
|
||||
std::swap(x, x2);
|
||||
std::swap(y, y2);
|
||||
std::swap(x1, x2);
|
||||
std::swap(y1, y2);
|
||||
stepx = -stepx;
|
||||
}
|
||||
if (y2 < 0 || y >= screen_height) return;
|
||||
if (y2 < 0 || y1 >= screen_height) return;
|
||||
|
||||
int x_low = x;
|
||||
int x_high = x;
|
||||
int x_low = x1;
|
||||
int x_high = x1;
|
||||
int frac_low = dx - frac_diff / 2;
|
||||
int frac_high = dx + frac_diff / 2;
|
||||
|
||||
@@ -149,10 +149,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
x_high += stepx;
|
||||
}
|
||||
|
||||
if (y < 0) {
|
||||
dash_count = (-y) % (dash + gap);
|
||||
if (y1 < 0) {
|
||||
dash_count = (-y1) % (dash + gap);
|
||||
auto adjust_frac = [&](int64 frac, int &x_bound) -> int {
|
||||
frac -= ((int64) dx) * ((int64) y);
|
||||
frac -= ((int64) dx) * ((int64) y1);
|
||||
if (frac >= 0) {
|
||||
int quotient = frac / dy;
|
||||
int remainder = frac % dy;
|
||||
@@ -163,17 +163,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
};
|
||||
frac_low = adjust_frac(frac_low, x_low);
|
||||
frac_high = adjust_frac(frac_high, x_high);
|
||||
y = 0;
|
||||
y1 = 0;
|
||||
}
|
||||
y2++;
|
||||
if (y2 > screen_height) {
|
||||
y2 = screen_height;
|
||||
}
|
||||
|
||||
while (y != y2) {
|
||||
while (y1 != y2) {
|
||||
if (dash_count < dash) {
|
||||
for (int x = x_low; x != x_high; x += stepx) {
|
||||
if (x >= 0 && x < screen_width) set_pixel(x, y);
|
||||
if (x >= 0 && x < screen_width) set_pixel(x, y1);
|
||||
}
|
||||
}
|
||||
if (frac_low >= 0) {
|
||||
@@ -184,7 +184,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
|
||||
x_high += stepx;
|
||||
frac_high -= dy;
|
||||
}
|
||||
y++;
|
||||
y1++;
|
||||
frac_low += dx;
|
||||
frac_high += dx;
|
||||
if (++dash_count >= dash + gap) dash_count = 0;
|
||||
|
||||
@@ -70,7 +70,7 @@ protected:
|
||||
*/
|
||||
blitters.insert(Blitters::value_type(this->name, this));
|
||||
} else {
|
||||
DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name);
|
||||
Debug(driver, 1, "Not registering blitter {} as it is not usable", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the requested blitter and return his class.
|
||||
* Find the requested blitter and return its class.
|
||||
* @param name the blitter to select.
|
||||
* @post Sets the blitter so GetCurrentBlitter() returns it too.
|
||||
*/
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
delete *GetActiveBlitter();
|
||||
*GetActiveBlitter() = newb;
|
||||
|
||||
DEBUG(driver, 1, "Successfully %s blitter '%s'", name.empty() ? "probed" : "loaded", newb->GetName());
|
||||
Debug(driver, 1, "Successfully {} blitter '{}'", name.empty() ? "probed" : "loaded", newb->GetName());
|
||||
return newb;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,9 +91,10 @@ public:
|
||||
this->InitNested(1);
|
||||
}
|
||||
|
||||
~BootstrapErrorWindow()
|
||||
void Close() override
|
||||
{
|
||||
_exit_game = true;
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
@@ -144,12 +145,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
~BootstrapContentDownloadStatusWindow()
|
||||
void Close() override
|
||||
{
|
||||
/* If we are not set to exit the game, it means the bootstrap failed. */
|
||||
if (!_exit_game) {
|
||||
new BootstrapErrorWindow();
|
||||
}
|
||||
this->BaseNetworkContentDownloadStatusWindow::Close();
|
||||
}
|
||||
|
||||
void OnDownloadComplete(ContentID cid) override
|
||||
@@ -162,7 +164,7 @@ public:
|
||||
|
||||
/* _exit_game is used to break out of the outer video driver's MainLoop. */
|
||||
_exit_game = true;
|
||||
delete this;
|
||||
this->Close();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -201,9 +203,10 @@ public:
|
||||
}
|
||||
|
||||
/** Stop listening to the content client events. */
|
||||
~BootstrapAskForDownloadWindow()
|
||||
void Close() override
|
||||
{
|
||||
_network_content_client.RemoveCallback(this);
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||
@@ -264,7 +267,7 @@ public:
|
||||
/* And once the meta data is received, start downloading it. */
|
||||
_network_content_client.Select(ci->id);
|
||||
new BootstrapContentDownloadStatusWindow();
|
||||
delete this;
|
||||
this->Close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ public:
|
||||
if (i < 9 && i < this->bridges->size()) {
|
||||
/* Build the requested bridge */
|
||||
this->BuildBridge(i);
|
||||
delete this;
|
||||
this->Close();
|
||||
return ES_HANDLED;
|
||||
}
|
||||
return ES_NOT_HANDLED;
|
||||
@@ -266,7 +266,7 @@ public:
|
||||
uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BBS_BRIDGE_LIST);
|
||||
if (i < this->bridges->size()) {
|
||||
this->BuildBridge(i);
|
||||
delete this;
|
||||
this->Close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -363,7 +363,7 @@ static WindowDesc _build_bridge_desc(
|
||||
*/
|
||||
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type)
|
||||
{
|
||||
DeleteWindowByClass(WC_BUILD_BRIDGE);
|
||||
CloseWindowByClass(WC_BUILD_BRIDGE);
|
||||
|
||||
/* Data type for the bridge.
|
||||
* Bit 16,15 = transport type,
|
||||
|
||||
@@ -1103,9 +1103,6 @@ struct BuildVehicleWindow : Window {
|
||||
* So we just hide it, and enlarge the Rename button by the now vacant place. */
|
||||
if (this->listview_mode) this->GetWidget<NWidgetStacked>(WID_BV_BUILD_SEL)->SetDisplayedPlane(SZSP_NONE);
|
||||
|
||||
/* disable renaming engines in network games if you are not the server */
|
||||
this->SetWidgetDisabledState(WID_BV_RENAME, _networking && !_network_server);
|
||||
|
||||
NWidgetCore *widget = this->GetWidget<NWidgetCore>(WID_BV_LIST);
|
||||
widget->tool_tip = STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP + type;
|
||||
|
||||
@@ -1192,8 +1189,7 @@ struct BuildVehicleWindow : Window {
|
||||
}
|
||||
|
||||
/* Collect available cargo types for filtering. */
|
||||
const CargoSpec *cs;
|
||||
FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
|
||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||
this->cargo_filter[filter_items] = cs->Index();
|
||||
this->cargo_filter_texts[filter_items] = cs->name;
|
||||
filter_items++;
|
||||
@@ -1236,7 +1232,7 @@ struct BuildVehicleWindow : Window {
|
||||
|
||||
if (!this->listview_mode) {
|
||||
/* Query for cost and refitted capacity */
|
||||
CommandCost ret = DoCommand(this->window_number, this->sel_engine | (cargo << 24), 0, DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type), nullptr);
|
||||
CommandCost ret = DoCommand(this->window_number, this->sel_engine | (cargo << 24), 0, DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type));
|
||||
if (ret.Succeeded()) {
|
||||
this->te.cost = ret.GetCost() - e->GetCost();
|
||||
this->te.capacity = _returned_refit_capacity;
|
||||
@@ -1616,7 +1612,10 @@ struct BuildVehicleWindow : Window {
|
||||
this->GenerateBuildList();
|
||||
this->vscroll->SetCount((uint)this->eng_list.size());
|
||||
|
||||
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WID_BV_RENAME, WIDGET_LIST_END);
|
||||
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WIDGET_LIST_END);
|
||||
|
||||
/* Disable renaming engines in network games if you are not the server. */
|
||||
this->SetWidgetDisabledState(WID_BV_RENAME, this->sel_engine == INVALID_ENGINE || (_networking && !_network_server));
|
||||
|
||||
this->DrawWidgets();
|
||||
|
||||
@@ -1693,7 +1692,7 @@ void ShowBuildVehicleWindow(TileIndex tile, VehicleType type)
|
||||
|
||||
assert(IsCompanyBuildableVehicleType(type));
|
||||
|
||||
DeleteWindowById(WC_BUILD_VEHICLE, num);
|
||||
CloseWindowById(WC_BUILD_VEHICLE, num);
|
||||
|
||||
new BuildVehicleWindow(&_build_vehicle_desc, tile, type);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ enum CargoType {
|
||||
CT_PLASTIC = 10,
|
||||
CT_FIZZY_DRINKS = 11,
|
||||
|
||||
NUM_ORIGINAL_CARGO = 12,
|
||||
NUM_CARGO = 64, ///< Maximal number of cargo types in a game.
|
||||
|
||||
CT_AUTO_REFIT = 0xFD, ///< Automatically choose cargo type when doing auto refitting.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "cargo_type.h"
|
||||
#include "vehicle_type.h"
|
||||
#include "core/multimap.hpp"
|
||||
#include "saveload/saveload.h"
|
||||
#include <list>
|
||||
|
||||
/** Unique identifier for a single cargo packet. */
|
||||
@@ -32,7 +33,7 @@ struct GoodsEntry; // forward-declare for Stage() and RerouteStalePackets()
|
||||
|
||||
template <class Tinst, class Tcont> class CargoList;
|
||||
class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
|
||||
extern const struct SaveLoad *GetCargoPacketDesc();
|
||||
extern SaveLoadTable GetCargoPacketDesc();
|
||||
|
||||
typedef uint32 TileOrStationID;
|
||||
|
||||
@@ -58,7 +59,7 @@ private:
|
||||
friend class VehicleCargoList;
|
||||
friend class StationCargoList;
|
||||
/** We want this to be saved, right? */
|
||||
friend const struct SaveLoad *GetCargoPacketDesc();
|
||||
friend SaveLoadTable GetCargoPacketDesc();
|
||||
public:
|
||||
/** Maximum number of items in a single cargo packet. */
|
||||
static const uint16 MAX_COUNT = UINT16_MAX;
|
||||
@@ -304,8 +305,8 @@ public:
|
||||
friend class StationCargoList;
|
||||
/** The super class ought to know what it's doing. */
|
||||
friend class CargoList<VehicleCargoList, CargoPacketList>;
|
||||
/** The vehicles have a cargo list (and we want that saved). */
|
||||
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
|
||||
/* So we can use private/protected variables in the saveload code */
|
||||
friend class SlVehicleCommon;
|
||||
|
||||
friend class CargoShift;
|
||||
friend class CargoTransfer;
|
||||
@@ -455,8 +456,8 @@ protected:
|
||||
public:
|
||||
/** The super class ought to know what it's doing. */
|
||||
friend class CargoList<StationCargoList, StationCargoPacketMap>;
|
||||
/** The stations, via GoodsEntry, have a CargoList. */
|
||||
friend const struct SaveLoad *GetGoodsDesc();
|
||||
/* So we can use private/protected variables in the saveload code */
|
||||
friend class SlStationGoods;
|
||||
|
||||
friend class CargoLoad;
|
||||
friend class CargoTransfer;
|
||||
|
||||
@@ -77,6 +77,28 @@ void SetupCargoForClimate(LandscapeID l)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cargo ID of a default cargo, if present.
|
||||
* @param l Landscape
|
||||
* @param ct Default cargo type.
|
||||
* @return ID number if the cargo exists, else #CT_INVALID
|
||||
*/
|
||||
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct)
|
||||
{
|
||||
assert(l < lengthof(_default_climate_cargo));
|
||||
|
||||
if (ct == CT_INVALID) return CT_INVALID;
|
||||
|
||||
assert(ct < lengthof(_default_climate_cargo[0]));
|
||||
CargoLabel cl = _default_climate_cargo[l][ct];
|
||||
/* Bzzt: check if cl is just an index into the cargo table */
|
||||
if (cl < lengthof(_default_cargo)) {
|
||||
cl = _default_cargo[cl].label;
|
||||
}
|
||||
|
||||
return GetCargoIDByLabel(cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cargo ID by cargo label.
|
||||
* @param cl Cargo type to get.
|
||||
@@ -127,8 +149,8 @@ SpriteID CargoSpec::GetCargoIcon() const
|
||||
return sprite;
|
||||
}
|
||||
|
||||
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
|
||||
uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored in the _sorted_cargo_specs array.
|
||||
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
|
||||
span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name.
|
||||
|
||||
/** Sort cargo specifications by their name. */
|
||||
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
|
||||
@@ -174,13 +196,16 @@ void InitializeSortedCargoSpecs()
|
||||
/* Sort cargo specifications by cargo class and name. */
|
||||
std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter);
|
||||
|
||||
/* Count the number of standard cargos and fill the mask. */
|
||||
_standard_cargo_mask = 0;
|
||||
|
||||
_sorted_standard_cargo_specs_size = 0;
|
||||
uint8 nb_standard_cargo = 0;
|
||||
for (const auto &cargo : _sorted_cargo_specs) {
|
||||
if (cargo->classes & CC_SPECIAL) break;
|
||||
_sorted_standard_cargo_specs_size++;
|
||||
nb_standard_cargo++;
|
||||
SetBit(_standard_cargo_mask, cargo->Index());
|
||||
}
|
||||
|
||||
/* _sorted_standard_cargo_specs is a subset of _sorted_cargo_specs. */
|
||||
_sorted_standard_cargo_specs = { _sorted_cargo_specs.data(), nb_standard_cargo };
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include "gfx_type.h"
|
||||
#include "strings_type.h"
|
||||
#include "landscape_type.h"
|
||||
#include "core/bitmath_func.hpp"
|
||||
#include "core/span_type.hpp"
|
||||
#include <vector>
|
||||
|
||||
/** Globally unique label of a cargo type. */
|
||||
@@ -59,7 +61,7 @@ struct CargoSpec {
|
||||
uint8 rating_colour;
|
||||
uint8 weight; ///< Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
|
||||
uint16 multiplier; ///< Capacity multiplier for vehicles. (8 fractional bits)
|
||||
uint32 initial_payment; ///< Initial payment rate before inflation is applied.
|
||||
int32 initial_payment; ///< Initial payment rate before inflation is applied.
|
||||
uint8 transit_days[2];
|
||||
|
||||
bool is_freight; ///< Cargo type is considered to be freight (affects train freight multiplier).
|
||||
@@ -177,10 +179,11 @@ extern CargoTypes _standard_cargo_mask;
|
||||
void SetupCargoForClimate(LandscapeID l);
|
||||
CargoID GetCargoIDByLabel(CargoLabel cl);
|
||||
CargoID GetCargoIDByBitnum(uint8 bitnum);
|
||||
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct);
|
||||
|
||||
void InitializeSortedCargoSpecs();
|
||||
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
|
||||
extern uint8 _sorted_standard_cargo_specs_size;
|
||||
extern span<const CargoSpec *> _sorted_standard_cargo_specs;
|
||||
|
||||
/**
|
||||
* Does cargo \a c have cargo class \a cc?
|
||||
@@ -193,13 +196,6 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc)
|
||||
return (CargoSpec::Get(c)->classes & cc) != 0;
|
||||
}
|
||||
|
||||
#define FOR_EACH_SET_CARGO_ID(var, cargo_bits) FOR_EACH_SET_BIT_EX(CargoID, var, CargoTypes, cargo_bits)
|
||||
|
||||
/**
|
||||
* Loop header for iterating over 'real' cargoes, sorted by name. Phony cargoes like regearing cargoes are skipped.
|
||||
* @param var Reference getting the cargospec.
|
||||
* @see CargoSpec
|
||||
*/
|
||||
#define FOR_ALL_SORTED_STANDARD_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_standard_cargo_specs_size && (var = _sorted_cargo_specs[index], true); index++)
|
||||
using SetCargoBitIterator = SetBitIterator<CargoID, CargoTypes>;
|
||||
|
||||
#endif /* CARGOTYPE_H */
|
||||
|
||||
@@ -415,6 +415,6 @@ static WindowDesc _cheats_desc(
|
||||
/** Open cheat window. */
|
||||
void ShowCheatWindow()
|
||||
{
|
||||
DeleteWindowById(WC_CHEATS, 0);
|
||||
CloseWindowById(WC_CHEATS, 0);
|
||||
new CheatWindow(&_cheats_desc);
|
||||
}
|
||||
|
||||
@@ -28,12 +28,9 @@ struct Cheats {
|
||||
Cheat switch_company; ///< change to another company
|
||||
Cheat money; ///< get rich or poor
|
||||
Cheat crossing_tunnels; ///< allow tunnels that cross each other
|
||||
Cheat dummy1; ///< empty cheat (build while in pause mode)
|
||||
Cheat no_jetcrash; ///< no jet will crash on small airports anymore
|
||||
Cheat dummy2; ///< empty cheat (change the climate of the map)
|
||||
Cheat change_date; ///< changes date ingame
|
||||
Cheat setup_prod; ///< setup raw-material production in game
|
||||
Cheat dummy3; ///< empty cheat (enable running el-engines on normal rail)
|
||||
Cheat edit_max_hl; ///< edit the maximum heightlevel; this is a cheat because of the fact that it needs to reset NewGRF game state and doing so as a simple configuration breaks the expectation of many
|
||||
};
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ static const Command _command_proc_table[] = {
|
||||
DEF_CMD(CmdBuildSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SIGNALS
|
||||
DEF_CMD(CmdRemoveSingleSignal, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SIGNALS
|
||||
DEF_CMD(CmdTerraformLand, CMD_ALL_TILES | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_TERRAFORM_LAND
|
||||
DEF_CMD(CmdBuildObject, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT
|
||||
DEF_CMD(CmdBuildObject, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_OBJECT
|
||||
DEF_CMD(CmdBuildTunnel, CMD_DEITY | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TUNNEL
|
||||
DEF_CMD(CmdRemoveFromRailStation, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_FROM_RAIL_STATION
|
||||
DEF_CMD(CmdConvertRail, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CONVERT_RAILD
|
||||
@@ -468,7 +468,7 @@ CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
|
||||
* @see CommandProc
|
||||
* @return the cost
|
||||
*/
|
||||
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text)
|
||||
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const std::string &text)
|
||||
{
|
||||
CommandCost res;
|
||||
|
||||
@@ -561,7 +561,7 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd)
|
||||
* @param my_cmd indicator if the command is from a company or server (to display error messages for a user)
|
||||
* @return \c true if the command succeeded, else \c false.
|
||||
*/
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd)
|
||||
{
|
||||
/* Cost estimation is generally only done when the
|
||||
* local user presses shift while doing something.
|
||||
@@ -641,7 +641,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
|
||||
* @param estimate_only whether to give only the estimate or also execute the command
|
||||
* @return the command cost of this function.
|
||||
*/
|
||||
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only)
|
||||
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd, bool estimate_only)
|
||||
{
|
||||
/* Prevent recursion; it gives a mess over the network */
|
||||
assert(_docommand_recursive == 0);
|
||||
@@ -706,7 +706,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
||||
if (!_networking || _generating_world || (cmd & CMD_NETWORK_COMMAND) != 0) {
|
||||
/* Log the failed command as well. Just to be able to be find
|
||||
* causes of desyncs due to bad command test implementations. */
|
||||
DEBUG(desync, 1, "cmdf: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
|
||||
Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
|
||||
}
|
||||
cur_company.Restore();
|
||||
return_dcpi(res);
|
||||
@@ -726,7 +726,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
|
||||
* reset the storages as we've not executed the command. */
|
||||
return_dcpi(CommandCost());
|
||||
}
|
||||
DEBUG(desync, 1, "cmd: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
|
||||
Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
|
||||
|
||||
/* Actually try and execute the command. If no cost-type is given
|
||||
* use the construction one */
|
||||
|
||||
@@ -32,15 +32,15 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID);
|
||||
*/
|
||||
#define return_cmd_error(errcode) return CommandCost(errcode);
|
||||
|
||||
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = nullptr);
|
||||
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const std::string &text = {});
|
||||
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags);
|
||||
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const char *text = nullptr, bool my_cmd = true);
|
||||
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const std::string &text = {}, bool my_cmd = true);
|
||||
bool DoCommandP(const CommandContainer *container, bool my_cmd = true);
|
||||
|
||||
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only);
|
||||
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd, bool estimate_only);
|
||||
|
||||
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company);
|
||||
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, CompanyID company);
|
||||
|
||||
extern Money _additional_cash_required;
|
||||
|
||||
|
||||
@@ -443,7 +443,7 @@ enum CommandPauseLevel {
|
||||
* @param text Additional text
|
||||
* @return The CommandCost of the command, which can be succeeded or failed.
|
||||
*/
|
||||
typedef CommandCost CommandProc(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
|
||||
typedef CommandCost CommandProc(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text);
|
||||
|
||||
/**
|
||||
* Define a command with the flags which belongs to it.
|
||||
@@ -482,7 +482,7 @@ struct CommandContainer {
|
||||
uint32 p2; ///< parameter p2.
|
||||
uint32 cmd; ///< command being executed.
|
||||
CommandCallback *callback; ///< any callback function executed upon successful completion of the command.
|
||||
char text[32 * MAX_CHAR_LENGTH]; ///< possible text sent for name changes etc, in bytes including '\0'.
|
||||
std::string text; ///< possible text sent for name changes etc.
|
||||
};
|
||||
|
||||
#endif /* COMMAND_TYPE_H */
|
||||
|
||||
@@ -98,28 +98,30 @@ struct CompanyProperties {
|
||||
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters.
|
||||
byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
|
||||
|
||||
Livery livery[LS_END];
|
||||
|
||||
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
|
||||
CompanySettings settings; ///< settings specific for each company
|
||||
|
||||
// TODO: Change some of these member variables to use relevant INVALID_xxx constants
|
||||
CompanyProperties()
|
||||
: name_2(0), name_1(0), president_name_1(0), president_name_2(0),
|
||||
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
|
||||
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
|
||||
months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
|
||||
terraform_limit(0), clear_limit(0), tree_limit(0), is_ai(false) {}
|
||||
terraform_limit(0), clear_limit(0), tree_limit(0), is_ai(false), engine_renew_list(nullptr) {}
|
||||
};
|
||||
|
||||
struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
|
||||
struct Company : CompanyProperties, CompanyPool::PoolItem<&_company_pool> {
|
||||
Company(uint16 name_1 = 0, bool is_ai = false);
|
||||
~Company();
|
||||
|
||||
Livery livery[LS_END];
|
||||
RailTypes avail_railtypes; ///< Rail types available to this company.
|
||||
RoadTypes avail_roadtypes; ///< Road types available to this company.
|
||||
|
||||
class AIInstance *ai_instance;
|
||||
class AIInfo *ai_info;
|
||||
|
||||
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
|
||||
CompanySettings settings; ///< settings specific for each company
|
||||
GroupStatistics group_all[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the ALL_GROUP group.
|
||||
GroupStatistics group_default[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the DEFAULT_GROUP group.
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ Company::Company(uint16 name_1, bool is_ai)
|
||||
this->clear_limit = (uint32)_settings_game.construction.clear_frame_burst << 16;
|
||||
this->tree_limit = (uint32)_settings_game.construction.tree_frame_burst << 16;
|
||||
|
||||
for (uint j = 0; j < 4; j++) this->share_owners[j] = COMPANY_SPECTATOR;
|
||||
for (uint j = 0; j < 4; j++) this->share_owners[j] = INVALID_OWNER;
|
||||
InvalidateWindowData(WC_PERFORMANCE_DETAIL, 0, INVALID_COMPANY);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ Company::~Company()
|
||||
{
|
||||
if (CleaningPool()) return;
|
||||
|
||||
DeleteCompanyWindows(this->index);
|
||||
CloseCompanyWindows(this->index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +115,7 @@ void SetLocalCompany(CompanyID new_company)
|
||||
_current_company = _local_company = new_company;
|
||||
|
||||
/* Delete any construction windows... */
|
||||
if (switching_company) DeleteConstructionWindows();
|
||||
if (switching_company) CloseConstructionWindows();
|
||||
|
||||
/* ... and redraw the whole screen. */
|
||||
MarkWholeScreenDirty();
|
||||
@@ -376,8 +376,7 @@ set_name:;
|
||||
MarkWholeScreenDirty();
|
||||
|
||||
if (c->is_ai) {
|
||||
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
|
||||
cni->FillData(c);
|
||||
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
|
||||
SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
|
||||
SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
|
||||
SetDParamStr(2, cni->company_name);
|
||||
@@ -755,21 +754,19 @@ void CompaniesYearlyLoop()
|
||||
* @param c the current company.
|
||||
* @param other the other company (use \c nullptr if not relevant).
|
||||
*/
|
||||
void CompanyNewsInformation::FillData(const Company *c, const Company *other)
|
||||
CompanyNewsInformation::CompanyNewsInformation(const Company *c, const Company *other)
|
||||
{
|
||||
SetDParam(0, c->index);
|
||||
GetString(this->company_name, STR_COMPANY_NAME, lastof(this->company_name));
|
||||
this->company_name = GetString(STR_COMPANY_NAME);
|
||||
|
||||
if (other == nullptr) {
|
||||
*this->other_company_name = '\0';
|
||||
} else {
|
||||
if (other != nullptr) {
|
||||
SetDParam(0, other->index);
|
||||
GetString(this->other_company_name, STR_COMPANY_NAME, lastof(this->other_company_name));
|
||||
this->other_company_name = GetString(STR_COMPANY_NAME);
|
||||
c = other;
|
||||
}
|
||||
|
||||
SetDParam(0, c->index);
|
||||
GetString(this->president_name, STR_PRESIDENT_NAME_MANAGER, lastof(this->president_name));
|
||||
this->president_name = GetString(STR_PRESIDENT_NAME_MANAGER);
|
||||
|
||||
this->colour = c->colour;
|
||||
this->face = c->face;
|
||||
@@ -807,7 +804,7 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason)
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);
|
||||
CompanyID company_id = (CompanyID)GB(p1, 16, 8);
|
||||
@@ -824,7 +821,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
|
||||
|
||||
/* Delete multiplayer progress bar */
|
||||
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
|
||||
CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
|
||||
|
||||
Company *c = DoStartupNewCompany(false);
|
||||
|
||||
@@ -843,7 +840,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
if (client_id == _network_own_client_id) {
|
||||
assert(_local_company == COMPANY_SPECTATOR);
|
||||
SetLocalCompany(c->index);
|
||||
if (!StrEmpty(_settings_client.network.default_company_pass)) {
|
||||
if (!_settings_client.network.default_company_pass.empty()) {
|
||||
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
|
||||
}
|
||||
|
||||
@@ -887,9 +884,8 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
if (!(flags & DC_EXEC)) return CommandCost();
|
||||
|
||||
/* Delete any open window of the company */
|
||||
DeleteCompanyWindows(c->index);
|
||||
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
|
||||
cni->FillData(c);
|
||||
CloseCompanyWindows(c->index);
|
||||
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
|
||||
|
||||
/* Show the bankrupt news */
|
||||
SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
|
||||
@@ -932,7 +928,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
CompanyManagerFace cmf = (CompanyManagerFace)p2;
|
||||
|
||||
@@ -956,7 +952,7 @@ CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
Colours colour = Extract<Colours, 0, 8>(p2);
|
||||
LiveryScheme scheme = Extract<LiveryScheme, 0, 8>(p1);
|
||||
@@ -1049,7 +1045,7 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
* @param name Name to search.
|
||||
* @return \c true if the name us unique (that is, not in use), else \c false.
|
||||
*/
|
||||
static bool IsUniqueCompanyName(const char *name)
|
||||
static bool IsUniqueCompanyName(const std::string &name)
|
||||
{
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (!c->name.empty() && c->name == name) return false;
|
||||
@@ -1067,9 +1063,9 @@ static bool IsUniqueCompanyName(const char *name)
|
||||
* @param text the new name or an empty string when resetting to the default
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
bool reset = StrEmpty(text);
|
||||
bool reset = text.empty();
|
||||
|
||||
if (!reset) {
|
||||
if (Utf8StringLength(text) >= MAX_LENGTH_COMPANY_NAME_CHARS) return CMD_ERROR;
|
||||
@@ -1095,7 +1091,7 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||
* @param name Name to search.
|
||||
* @return \c true if the name us unique (that is, not in use), else \c false.
|
||||
*/
|
||||
static bool IsUniquePresidentName(const char *name)
|
||||
static bool IsUniquePresidentName(const std::string &name)
|
||||
{
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (!c->president_name.empty() && c->president_name == name) return false;
|
||||
@@ -1113,9 +1109,9 @@ static bool IsUniquePresidentName(const char *name)
|
||||
* @param text the new name or an empty string when resetting to the default
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
bool reset = StrEmpty(text);
|
||||
bool reset = text.empty();
|
||||
|
||||
if (!reset) {
|
||||
if (Utf8StringLength(text) >= MAX_LENGTH_PRESIDENT_NAME_CHARS) return CMD_ERROR;
|
||||
@@ -1131,10 +1127,7 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
c->president_name = text;
|
||||
|
||||
if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) {
|
||||
char buf[80];
|
||||
|
||||
seprintf(buf, lastof(buf), "%s Transport", text);
|
||||
DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, buf);
|
||||
DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, text + " Transport");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1201,7 +1194,7 @@ uint32 CompanyInfrastructure::GetTramTotal() const
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
if (!_settings_game.economy.give_money) return CMD_ERROR;
|
||||
|
||||
@@ -1220,13 +1213,11 @@ CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
cur_company.Restore();
|
||||
|
||||
if (_networking) {
|
||||
char dest_company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH];
|
||||
SetDParam(0, dest_company);
|
||||
GetString(dest_company_name, STR_COMPANY_NAME, lastof(dest_company_name));
|
||||
std::string dest_company_name = GetString(STR_COMPANY_NAME);
|
||||
|
||||
char from_company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH];
|
||||
SetDParam(0, _current_company);
|
||||
GetString(from_company_name, STR_COMPANY_NAME, lastof(from_company_name));
|
||||
std::string from_company_name = GetString(STR_COMPANY_NAME);
|
||||
|
||||
NetworkTextMessage(NETWORK_ACTION_GIVE_MONEY, GetDrawStringCompanyColour(_current_company), false, from_company_name, dest_company_name, amount.GetCost());
|
||||
}
|
||||
|
||||
@@ -777,11 +777,11 @@ public:
|
||||
|
||||
case WID_SCL_PRI_COL_DROPDOWN: {
|
||||
this->square = GetSpriteSize(SPR_SQUARE);
|
||||
int padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10;
|
||||
int string_padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10;
|
||||
for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) {
|
||||
size->width = std::max(size->width, GetStringBoundingBox(*id).width + padding);
|
||||
size->width = std::max(size->width, GetStringBoundingBox(*id).width + string_padding);
|
||||
}
|
||||
size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + padding);
|
||||
size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + string_padding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1594,7 +1594,7 @@ public:
|
||||
|
||||
/* Cancel button */
|
||||
case WID_SCMF_CANCEL:
|
||||
delete this;
|
||||
this->Close();
|
||||
break;
|
||||
|
||||
/* Load button */
|
||||
@@ -2775,7 +2775,7 @@ struct BuyCompanyWindow : Window {
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BC_NO:
|
||||
delete this;
|
||||
this->Close();
|
||||
break;
|
||||
|
||||
case WID_BC_YES:
|
||||
|
||||
@@ -23,7 +23,7 @@ void ShowCompanyFinances(CompanyID company);
|
||||
void ShowCompany(CompanyID company);
|
||||
|
||||
void InvalidateCompanyWindows(const Company *c);
|
||||
void DeleteCompanyWindows(CompanyID company);
|
||||
void CloseCompanyWindows(CompanyID company);
|
||||
void DirtyCompanyInfrastructureWindows(CompanyID company);
|
||||
|
||||
#endif /* COMPANY_GUI_H */
|
||||
|
||||
@@ -59,7 +59,7 @@ static void IConsoleWriteToLogFile(const char *string)
|
||||
fwrite("\n", 1, 1, _iconsole_output_file) != 1) {
|
||||
fclose(_iconsole_output_file);
|
||||
_iconsole_output_file = nullptr;
|
||||
IConsolePrintF(CC_DEFAULT, "cannot write to log file");
|
||||
IConsolePrint(CC_ERROR, "Cannot write to console log file; closing the log file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ static void IConsoleWriteToLogFile(const char *string)
|
||||
bool CloseConsoleLogIfActive()
|
||||
{
|
||||
if (_iconsole_output_file != nullptr) {
|
||||
IConsolePrintF(CC_DEFAULT, "file output complete");
|
||||
IConsolePrint(CC_INFO, "Console log file closed.");
|
||||
fclose(_iconsole_output_file);
|
||||
_iconsole_output_file = nullptr;
|
||||
return true;
|
||||
@@ -88,14 +88,13 @@ void IConsoleFree()
|
||||
* as well as to a logfile. If the network server is a dedicated server, all activities
|
||||
* are also logged. All lines to print are added to a temporary buffer which can be
|
||||
* used as a history to print them onscreen
|
||||
* @param colour_code the colour of the command. Red in case of errors, etc.
|
||||
* @param string the message entered or output on the console (notice, error, etc.)
|
||||
* @param colour_code The colour of the command.
|
||||
* @param string The message to output on the console (notice, error, etc.)
|
||||
*/
|
||||
void IConsolePrint(TextColour colour_code, const char *string)
|
||||
void IConsolePrint(TextColour colour_code, const std::string &string)
|
||||
{
|
||||
assert(IsValidConsoleColour(colour_code));
|
||||
|
||||
char *str;
|
||||
if (_redirect_console_to_client != INVALID_CLIENT_ID) {
|
||||
/* Redirect the string to the client */
|
||||
NetworkServerSendRcon(_redirect_console_to_client, colour_code, string);
|
||||
@@ -109,9 +108,9 @@ void IConsolePrint(TextColour colour_code, const char *string)
|
||||
|
||||
/* Create a copy of the string, strip if of colours and invalid
|
||||
* characters and (when applicable) assign it to the console buffer */
|
||||
str = stredup(string);
|
||||
char *str = stredup(string.c_str());
|
||||
str_strip_colours(str);
|
||||
str_validate(str, str + strlen(str));
|
||||
StrMakeValidInPlace(str);
|
||||
|
||||
if (_network_dedicated) {
|
||||
NetworkAdminConsole("console", str);
|
||||
@@ -126,59 +125,6 @@ void IConsolePrint(TextColour colour_code, const char *string)
|
||||
IConsoleGUIPrint(colour_code, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the printing of text entered into the console or redirected there
|
||||
* by any other means. Uses printf() style format, for more information look
|
||||
* at IConsolePrint()
|
||||
*/
|
||||
void CDECL IConsolePrintF(TextColour colour_code, const char *format, ...)
|
||||
{
|
||||
assert(IsValidConsoleColour(colour_code));
|
||||
|
||||
va_list va;
|
||||
char buf[ICON_MAX_STREAMSIZE];
|
||||
|
||||
va_start(va, format);
|
||||
vseprintf(buf, lastof(buf), format, va);
|
||||
va_end(va);
|
||||
|
||||
IConsolePrint(colour_code, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* It is possible to print debugging information to the console,
|
||||
* which is achieved by using this function. Can only be used by
|
||||
* debug() in debug.cpp. You need at least a level 2 (developer) for debugging
|
||||
* messages to show up
|
||||
* @param dbg debugging category
|
||||
* @param string debugging message
|
||||
*/
|
||||
void IConsoleDebug(const char *dbg, const char *string)
|
||||
{
|
||||
if (_settings_client.gui.developer <= 1) return;
|
||||
IConsolePrintF(CC_DEBUG, "dbg: [%s] %s", dbg, string);
|
||||
}
|
||||
|
||||
/**
|
||||
* It is possible to print warnings to the console. These are mostly
|
||||
* errors or mishaps, but non-fatal. You need at least a level 1 (developer) for
|
||||
* debugging messages to show up
|
||||
*/
|
||||
void IConsoleWarning(const char *string)
|
||||
{
|
||||
if (_settings_client.gui.developer == 0) return;
|
||||
IConsolePrintF(CC_WARNING, "WARNING: %s", string);
|
||||
}
|
||||
|
||||
/**
|
||||
* It is possible to print error information to the console. This can include
|
||||
* game errors, or errors in general you would want the user to notice
|
||||
*/
|
||||
void IConsoleError(const char *string)
|
||||
{
|
||||
IConsolePrintF(CC_ERROR, "ERROR: %s", string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change a string into its number representation. Supports
|
||||
* decimal and hexadecimal numbers as well as 'on'/'off' 'true'/'false'
|
||||
@@ -244,7 +190,7 @@ static std::string RemoveUnderscores(std::string name)
|
||||
/* static */ void IConsole::AliasRegister(const std::string &name, const std::string &cmd)
|
||||
{
|
||||
auto result = IConsole::Aliases().try_emplace(RemoveUnderscores(name), name, cmd);
|
||||
if (!result.second) IConsoleError("an alias with this name already exists; insertion aborted");
|
||||
if (!result.second) IConsolePrint(CC_ERROR, "An alias with the name '{}' already exists.", name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,10 +217,10 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
|
||||
char alias_buffer[ICON_MAX_STREAMSIZE] = { '\0' };
|
||||
char *alias_stream = alias_buffer;
|
||||
|
||||
DEBUG(console, 6, "Requested command is an alias; parsing...");
|
||||
Debug(console, 6, "Requested command is an alias; parsing...");
|
||||
|
||||
if (recurse_count > ICON_MAX_RECURSE) {
|
||||
IConsoleError("Too many alias expansions, recursion limit reached. Aborting");
|
||||
IConsolePrint(CC_ERROR, "Too many alias expansions, recursion limit reached.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -320,8 +266,8 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
|
||||
int param = *cmdptr - 'A';
|
||||
|
||||
if (param < 0 || param >= tokencount) {
|
||||
IConsoleError("too many or wrong amount of parameters passed to alias, aborting");
|
||||
IConsolePrintF(CC_WARNING, "Usage of alias '%s': %s", alias->name.c_str(), alias->cmdline.c_str());
|
||||
IConsolePrint(CC_ERROR, "Too many or wrong amount of parameters passed to alias.");
|
||||
IConsolePrint(CC_HELP, "Usage of alias '{}': '{}'.", alias->name, alias->cmdline);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -340,7 +286,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
|
||||
}
|
||||
|
||||
if (alias_stream >= lastof(alias_buffer) - 1) {
|
||||
IConsoleError("Requested alias execution would overflow execution buffer");
|
||||
IConsolePrint(CC_ERROR, "Requested alias execution would overflow execution buffer.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -366,13 +312,12 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
|
||||
|
||||
for (cmdptr = cmdstr; *cmdptr != '\0'; cmdptr++) {
|
||||
if (!IsValidChar(*cmdptr, CS_ALPHANUMERAL)) {
|
||||
IConsoleError("command contains malformed characters, aborting");
|
||||
IConsolePrintF(CC_ERROR, "ERROR: command was: '%s'", cmdstr);
|
||||
IConsolePrint(CC_ERROR, "Command '{}' contains malformed characters.", cmdstr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(console, 4, "Executing cmdline: '%s'", cmdstr);
|
||||
Debug(console, 4, "Executing cmdline: '{}'", cmdstr);
|
||||
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
memset(&tokenstream, 0, sizeof(tokenstream));
|
||||
@@ -382,7 +327,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
|
||||
* of characters in our stream or the max amount of tokens we can handle */
|
||||
for (cmdptr = cmdstr, t_index = 0, tstream_i = 0; *cmdptr != '\0'; cmdptr++) {
|
||||
if (tstream_i >= lengthof(tokenstream)) {
|
||||
IConsoleError("command line too long");
|
||||
IConsolePrint(CC_ERROR, "Command line too long.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -403,7 +348,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
|
||||
longtoken = !longtoken;
|
||||
if (!foundtoken) {
|
||||
if (t_index >= lengthof(tokens)) {
|
||||
IConsoleError("command line too long");
|
||||
IConsolePrint(CC_ERROR, "Command line too long.");
|
||||
return;
|
||||
}
|
||||
tokens[t_index++] = &tokenstream[tstream_i];
|
||||
@@ -421,7 +366,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
|
||||
|
||||
if (!foundtoken) {
|
||||
if (t_index >= lengthof(tokens)) {
|
||||
IConsoleError("command line too long");
|
||||
IConsolePrint(CC_ERROR, "Command line too long.");
|
||||
return;
|
||||
}
|
||||
tokens[t_index++] = &tokenstream[tstream_i - 1];
|
||||
@@ -432,7 +377,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
|
||||
}
|
||||
|
||||
for (uint i = 0; i < lengthof(tokens) && tokens[i] != nullptr; i++) {
|
||||
DEBUG(console, 8, "Token %d is: '%s'", i, tokens[i]);
|
||||
Debug(console, 8, "Token {} is: '{}'", i, tokens[i]);
|
||||
}
|
||||
|
||||
if (StrEmpty(tokens[0])) return; // don't execute empty commands
|
||||
@@ -462,5 +407,5 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
|
||||
return;
|
||||
}
|
||||
|
||||
IConsoleError("command not found");
|
||||
IConsolePrint(CC_ERROR, "Command '{}' not found.", tokens[0]);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@
|
||||
#define CONSOLE_FUNC_H
|
||||
|
||||
#include "console_type.h"
|
||||
#include "3rdparty/fmt/format.h"
|
||||
|
||||
/* console modes */
|
||||
extern IConsoleModes _iconsole_mode;
|
||||
@@ -21,11 +22,29 @@ void IConsoleFree();
|
||||
void IConsoleClose();
|
||||
|
||||
/* console output */
|
||||
void IConsolePrint(TextColour colour_code, const char *string);
|
||||
void CDECL IConsolePrintF(TextColour colour_code, const char *format, ...) WARN_FORMAT(2, 3);
|
||||
void IConsoleDebug(const char *dbg, const char *string);
|
||||
void IConsoleWarning(const char *string);
|
||||
void IConsoleError(const char *string);
|
||||
void IConsolePrint(TextColour colour_code, const std::string &string);
|
||||
|
||||
/**
|
||||
* Handle the printing of text entered into the console or redirected there
|
||||
* by any other means. Text can be redirected to other clients in a network game
|
||||
* as well as to a logfile. If the network server is a dedicated server, all activities
|
||||
* are also logged. All lines to print are added to a temporary buffer which can be
|
||||
* used as a history to print them onscreen
|
||||
* @param colour_code The colour of the command.
|
||||
* @param format_string The formatting string to tell what to do with the remaining arguments.
|
||||
* @param first_arg The first argument to the format.
|
||||
* @param other_args The other arguments to the format.
|
||||
* @tparam T The type of formatting parameter.
|
||||
* @tparam A The type of the first argument.
|
||||
* @tparam Args The types of the other arguments.
|
||||
*/
|
||||
template <typename T, typename A, typename ... Args>
|
||||
static inline void IConsolePrint(TextColour colour_code, const T &format, A first_arg, Args&&... other_args)
|
||||
{
|
||||
/* The separate first_arg argument is added to aid overloading.
|
||||
* Otherwise the calls that do no need formatting will still use this function. */
|
||||
IConsolePrint(colour_code, fmt::format(format, first_arg, other_args...));
|
||||
}
|
||||
|
||||
/* Parser */
|
||||
void IConsoleCmdExec(const char *cmdstr, const uint recurse_count = 0);
|
||||
|
||||
@@ -201,10 +201,11 @@ struct IConsoleWindow : Window
|
||||
#endif // __EMSCRIPTEN__
|
||||
}
|
||||
|
||||
~IConsoleWindow()
|
||||
void Close() override
|
||||
{
|
||||
_iconsole_mode = ICONSOLE_CLOSED;
|
||||
VideoDriver::GetInstance()->EditBoxLostFocus();
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,7 +340,7 @@ struct IConsoleWindow : Window
|
||||
/* We always want the ] at the left side; we always force these strings to be left
|
||||
* aligned anyway. So enforce this in all cases by adding a left-to-right marker,
|
||||
* otherwise it will be drawn at the wrong side with right-to-left texts. */
|
||||
IConsolePrintF(CC_COMMAND, LRM "] %s", _iconsole_cmdline.buf);
|
||||
IConsolePrint(CC_COMMAND, LRM "] {}", _iconsole_cmdline.buf);
|
||||
const char *cmd = IConsoleHistoryAdd(_iconsole_cmdline.buf);
|
||||
IConsoleClearCommand();
|
||||
|
||||
@@ -451,10 +452,10 @@ void IConsoleGUIInit()
|
||||
IConsoleLine::Reset();
|
||||
memset(_iconsole_history, 0, sizeof(_iconsole_history));
|
||||
|
||||
IConsolePrintF(CC_WARNING, "OpenTTD Game Console Revision 7 - %s", _openttd_revision);
|
||||
IConsolePrint(CC_WHITE, "------------------------------------");
|
||||
IConsolePrint(CC_WHITE, "use \"help\" for more information");
|
||||
IConsolePrint(CC_WHITE, "");
|
||||
IConsolePrint(TC_LIGHT_BLUE, "OpenTTD Game Console Revision 7 - {}", _openttd_revision);
|
||||
IConsolePrint(CC_WHITE, "------------------------------------");
|
||||
IConsolePrint(CC_WHITE, "use \"help\" for more information.");
|
||||
IConsolePrint(CC_WHITE, "");
|
||||
IConsoleClearCommand();
|
||||
}
|
||||
|
||||
@@ -511,7 +512,7 @@ void IConsoleSwitch()
|
||||
#endif
|
||||
break;
|
||||
case ICONSOLE_OPENED: case ICONSOLE_FULL:
|
||||
DeleteWindowById(WC_CONSOLE, 0);
|
||||
CloseWindowById(WC_CONSOLE, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ enum ConsoleHookResult {
|
||||
* effect they produce are carried out. The arguments to the commands
|
||||
* are given to them, each input word separated by a double-quote (") is an argument
|
||||
* If you want to handle multiple words as one, enclose them in double-quotes
|
||||
* eg. 'say "hello sexy boy"'
|
||||
* eg. 'say "hello everybody"'
|
||||
*/
|
||||
typedef bool IConsoleCmdProc(byte argc, char *argv[]);
|
||||
typedef ConsoleHookResult IConsoleHook(bool echo);
|
||||
|
||||
@@ -23,6 +23,7 @@ enum IConsoleModes {
|
||||
static const TextColour CC_DEFAULT = TC_SILVER; ///< Default colour of the console.
|
||||
static const TextColour CC_ERROR = TC_RED; ///< Colour for error lines.
|
||||
static const TextColour CC_WARNING = TC_LIGHT_BLUE; ///< Colour for warning lines.
|
||||
static const TextColour CC_HELP = TC_LIGHT_BLUE; ///< Colour for help lines.
|
||||
static const TextColour CC_INFO = TC_YELLOW; ///< Colour for information lines.
|
||||
static const TextColour CC_DEBUG = TC_LIGHT_BROWN; ///< Colour for debug output.
|
||||
static const TextColour CC_COMMAND = TC_GOLD; ///< Colour for the console's commands.
|
||||
|
||||
@@ -51,7 +51,7 @@ struct Backup {
|
||||
{
|
||||
/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
|
||||
* Exceptions are especially used to abort world generation. */
|
||||
DEBUG(misc, 0, "%s:%d: Backed-up value was not restored!", this->file, this->line);
|
||||
Debug(misc, 0, "{}:{}: Backed-up value was not restored!", this->file, this->line);
|
||||
this->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,45 +320,55 @@ static inline T ROR(const T x, const uint8 n)
|
||||
return (T)(x >> n | x << (sizeof(x) * 8 - n));
|
||||
}
|
||||
|
||||
/**
|
||||
* Do an operation for each set bit in a value.
|
||||
*
|
||||
* This macros is used to do an operation for each set
|
||||
* bit in a variable. The second parameter is a
|
||||
* variable that is used as the bit position counter.
|
||||
* The fourth parameter is an expression of the bits
|
||||
* we need to iterate over. This expression will be
|
||||
* evaluated once.
|
||||
*
|
||||
* @param Tbitpos_type Type of the position counter variable.
|
||||
* @param bitpos_var The position counter variable.
|
||||
* @param Tbitset_type Type of the bitset value.
|
||||
* @param bitset_value The bitset value which we check for bits.
|
||||
*
|
||||
* @see FOR_EACH_SET_BIT
|
||||
*/
|
||||
#define FOR_EACH_SET_BIT_EX(Tbitpos_type, bitpos_var, Tbitset_type, bitset_value) \
|
||||
for ( \
|
||||
Tbitset_type ___FESBE_bits = (bitpos_var = (Tbitpos_type)0, bitset_value); \
|
||||
___FESBE_bits != (Tbitset_type)0; \
|
||||
___FESBE_bits = (Tbitset_type)(___FESBE_bits >> 1), bitpos_var++ \
|
||||
) \
|
||||
if ((___FESBE_bits & 1) != 0)
|
||||
/**
|
||||
* Iterable ensemble of each set bit in a value.
|
||||
* @tparam Tbitpos Type of the position variable.
|
||||
* @tparam Tbitset Type of the bitset value.
|
||||
*/
|
||||
template <typename Tbitpos = uint, typename Tbitset = uint>
|
||||
struct SetBitIterator {
|
||||
struct Iterator {
|
||||
typedef Tbitpos value_type;
|
||||
typedef value_type *pointer;
|
||||
typedef value_type &reference;
|
||||
typedef size_t difference_type;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
/**
|
||||
* Do an operation for each set set bit in a value.
|
||||
*
|
||||
* This macros is used to do an operation for each set
|
||||
* bit in a variable. The first parameter is a variable
|
||||
* that is used as the bit position counter.
|
||||
* The second parameter is an expression of the bits
|
||||
* we need to iterate over. This expression will be
|
||||
* evaluated once.
|
||||
*
|
||||
* @param bitpos_var The position counter variable.
|
||||
* @param bitset_value The value which we check for set bits.
|
||||
*/
|
||||
#define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value)
|
||||
explicit Iterator(Tbitset bitset) : bitset(bitset), bitpos(static_cast<Tbitpos>(0))
|
||||
{
|
||||
this->Validate();
|
||||
}
|
||||
|
||||
bool operator==(const Iterator &other) const
|
||||
{
|
||||
return this->bitset == other.bitset && (this->bitset == 0 || this->bitpos == other.bitpos);
|
||||
}
|
||||
bool operator!=(const Iterator &other) const { return !(*this == other); }
|
||||
Tbitpos operator*() const { return this->bitpos; }
|
||||
Iterator & operator++() { this->Next(); this->Validate(); return *this; }
|
||||
|
||||
private:
|
||||
Tbitset bitset;
|
||||
Tbitpos bitpos;
|
||||
void Validate()
|
||||
{
|
||||
while (this->bitset != 0 && (this->bitset & 1) == 0) this->Next();
|
||||
}
|
||||
void Next()
|
||||
{
|
||||
this->bitset = static_cast<Tbitset>(this->bitset >> 1);
|
||||
this->bitpos++;
|
||||
}
|
||||
};
|
||||
|
||||
SetBitIterator(Tbitset bitset) : bitset(bitset) {}
|
||||
Iterator begin() { return Iterator(this->bitset); }
|
||||
Iterator end() { return Iterator(static_cast<Tbitset>(0)); }
|
||||
bool empty() { return this->begin() == this->end(); }
|
||||
|
||||
private:
|
||||
Tbitset bitset;
|
||||
};
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* Make endian swapping use Apple's macros to increase speed
|
||||
|
||||
@@ -274,7 +274,7 @@ class Kdtree {
|
||||
}
|
||||
|
||||
template <typename Outputter>
|
||||
void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, Outputter outputter) const
|
||||
void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, const Outputter &outputter) const
|
||||
{
|
||||
/* Dimension index of current level */
|
||||
int dim = level % 2;
|
||||
@@ -458,7 +458,7 @@ public:
|
||||
* @param outputter Callback used to return values from the search.
|
||||
*/
|
||||
template <typename Outputter>
|
||||
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, Outputter outputter) const
|
||||
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, const Outputter &outputter) const
|
||||
{
|
||||
assert(x1 < x2);
|
||||
assert(y1 < y2);
|
||||
|
||||
@@ -12,60 +12,97 @@
|
||||
|
||||
#include "math_func.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#ifdef __has_builtin
|
||||
# if __has_builtin(__builtin_add_overflow) && __has_builtin(__builtin_sub_overflow) && __has_builtin(__builtin_mul_overflow)
|
||||
# define HAS_OVERFLOW_BUILTINS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Overflow safe template for integers, i.e. integers that will never overflow
|
||||
* you multiply the maximum value with 2, or add 2, or subtract something from
|
||||
* the minimum value, etc.
|
||||
* @param T the type these integers are stored with.
|
||||
* @param T_MAX the maximum value for the integers.
|
||||
* @param T_MIN the minimum value for the integers.
|
||||
*/
|
||||
template <class T, T T_MAX, T T_MIN>
|
||||
template <class T>
|
||||
class OverflowSafeInt
|
||||
{
|
||||
private:
|
||||
static constexpr T T_MAX = std::numeric_limits<T>::max();
|
||||
static constexpr T T_MIN = std::numeric_limits<T>::min();
|
||||
|
||||
/** The non-overflow safe backend to store the value in. */
|
||||
T m_value;
|
||||
public:
|
||||
OverflowSafeInt() : m_value(0) { }
|
||||
constexpr OverflowSafeInt() : m_value(0) { }
|
||||
|
||||
OverflowSafeInt(const OverflowSafeInt& other) { this->m_value = other.m_value; }
|
||||
OverflowSafeInt(const int64 int_) { this->m_value = int_; }
|
||||
constexpr OverflowSafeInt(const OverflowSafeInt& other) : m_value(other.m_value) { }
|
||||
constexpr OverflowSafeInt(const int64 int_) : m_value(int_) { }
|
||||
|
||||
inline OverflowSafeInt& operator = (const OverflowSafeInt& other) { this->m_value = other.m_value; return *this; }
|
||||
inline constexpr OverflowSafeInt& operator = (const OverflowSafeInt& other) { this->m_value = other.m_value; return *this; }
|
||||
|
||||
inline OverflowSafeInt operator - () const { return OverflowSafeInt(-this->m_value); }
|
||||
inline constexpr OverflowSafeInt operator - () const { return OverflowSafeInt(this->m_value == T_MIN ? T_MAX : -this->m_value); }
|
||||
|
||||
/**
|
||||
* Safe implementation of addition.
|
||||
* @param other the amount to add
|
||||
* @note when the addition would yield more than T_MAX (or less than T_MIN),
|
||||
* it will be T_MAX (respectively T_MIN).
|
||||
* @note when the addition would yield more than T_MAX, it will be T_MAX.
|
||||
*/
|
||||
inline OverflowSafeInt& operator += (const OverflowSafeInt& other)
|
||||
inline constexpr OverflowSafeInt& operator += (const OverflowSafeInt& other)
|
||||
{
|
||||
if ((T_MAX - abs(other.m_value)) < abs(this->m_value) &&
|
||||
(this->m_value < 0) == (other.m_value < 0)) {
|
||||
this->m_value = (this->m_value < 0) ? T_MIN : T_MAX ;
|
||||
#ifdef HAS_OVERFLOW_BUILTINS
|
||||
if (unlikely(__builtin_add_overflow(this->m_value, other.m_value, &this->m_value))) {
|
||||
this->m_value = (other.m_value < 0) ? T_MIN : T_MAX;
|
||||
}
|
||||
#else
|
||||
if (this->m_value > 0 && other.m_value > 0 && (T_MAX - other.m_value) < this->m_value) {
|
||||
this->m_value = T_MAX;
|
||||
} else if (this->m_value < 0 && other.m_value < 0 && (this->m_value == T_MIN || other.m_value == T_MIN || ((T_MAX + this->m_value) + other.m_value < (T_MIN + T_MAX)))) {
|
||||
this->m_value = T_MIN;
|
||||
} else {
|
||||
this->m_value += other.m_value;
|
||||
}
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Operators for addition and subtraction */
|
||||
inline OverflowSafeInt operator + (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result += other; return result; }
|
||||
inline OverflowSafeInt operator + (const int other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
||||
inline OverflowSafeInt operator + (const uint other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
||||
inline OverflowSafeInt& operator -= (const OverflowSafeInt& other) { return *this += (-other); }
|
||||
inline OverflowSafeInt operator - (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result -= other; return result; }
|
||||
inline OverflowSafeInt operator - (const int other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
||||
inline OverflowSafeInt operator - (const uint other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
||||
/**
|
||||
* Safe implementation of subtraction.
|
||||
* @param other the amount to subtract
|
||||
* @note when the subtraction would yield less than T_MIN, it will be T_MIN.
|
||||
*/
|
||||
inline constexpr OverflowSafeInt& operator -= (const OverflowSafeInt& other)
|
||||
{
|
||||
#ifdef HAS_OVERFLOW_BUILTINS
|
||||
if (unlikely(__builtin_sub_overflow(this->m_value, other.m_value, &this->m_value))) {
|
||||
this->m_value = (other.m_value < 0) ? T_MAX : T_MIN;
|
||||
}
|
||||
#else
|
||||
if (this->m_value > 0 && other.m_value < 0 && (T_MAX + other.m_value) < this->m_value) {
|
||||
this->m_value = T_MAX;
|
||||
} else if (this->m_value < 0 && other.m_value > 0 && (T_MAX + this->m_value) < (T_MIN + T_MAX) + other.m_value) {
|
||||
this->m_value = T_MIN;
|
||||
} else {
|
||||
this->m_value -= other.m_value;
|
||||
}
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline OverflowSafeInt& operator ++ () { return *this += 1; }
|
||||
inline OverflowSafeInt& operator -- () { return *this += -1; }
|
||||
inline OverflowSafeInt operator ++ (int) { OverflowSafeInt org = *this; *this += 1; return org; }
|
||||
inline OverflowSafeInt operator -- (int) { OverflowSafeInt org = *this; *this += -1; return org; }
|
||||
/* Operators for addition and subtraction. */
|
||||
inline constexpr OverflowSafeInt operator + (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result += other; return result; }
|
||||
inline constexpr OverflowSafeInt operator + (const int other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
||||
inline constexpr OverflowSafeInt operator + (const uint other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
|
||||
inline constexpr OverflowSafeInt operator - (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result -= other; return result; }
|
||||
inline constexpr OverflowSafeInt operator - (const int other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
||||
inline constexpr OverflowSafeInt operator - (const uint other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
|
||||
|
||||
inline constexpr OverflowSafeInt& operator ++ () { return *this += 1; }
|
||||
inline constexpr OverflowSafeInt& operator -- () { return *this += -1; }
|
||||
inline constexpr OverflowSafeInt operator ++ (int) { OverflowSafeInt org = *this; *this += 1; return org; }
|
||||
inline constexpr OverflowSafeInt operator -- (int) { OverflowSafeInt org = *this; *this += -1; return org; }
|
||||
|
||||
/**
|
||||
* Safe implementation of multiplication.
|
||||
@@ -73,83 +110,107 @@ public:
|
||||
* @note when the multiplication would yield more than T_MAX (or less than T_MIN),
|
||||
* it will be T_MAX (respectively T_MIN).
|
||||
*/
|
||||
inline OverflowSafeInt& operator *= (const int factor)
|
||||
inline constexpr OverflowSafeInt& operator *= (const int factor)
|
||||
{
|
||||
if (factor != 0 && (T_MAX / abs(factor)) < abs(this->m_value)) {
|
||||
this->m_value = ((this->m_value < 0) == (factor < 0)) ? T_MAX : T_MIN ;
|
||||
} else {
|
||||
this->m_value *= factor ;
|
||||
#ifdef HAS_OVERFLOW_BUILTINS
|
||||
const bool is_result_positive = (this->m_value < 0) == (factor < 0); // -ve * -ve == +ve
|
||||
if (unlikely(__builtin_mul_overflow(this->m_value, factor, &this->m_value))) {
|
||||
this->m_value = is_result_positive ? T_MAX : T_MIN;
|
||||
}
|
||||
#else
|
||||
if (factor == -1) {
|
||||
this->m_value = (this->m_value == T_MIN) ? T_MAX : -this->m_value;
|
||||
} else if (factor > 0 && this->m_value > 0 && (T_MAX / factor) < this->m_value) {
|
||||
this->m_value = T_MAX;
|
||||
} else if (factor > 0 && this->m_value < 0 && (T_MIN / factor) > this->m_value) {
|
||||
this->m_value = T_MIN;
|
||||
} else if (factor < 0 && this->m_value > 0 && (T_MIN / factor) < this->m_value) {
|
||||
this->m_value = T_MIN;
|
||||
} else if (factor < 0 && this->m_value < 0 && (T_MAX / factor) > this->m_value) {
|
||||
this->m_value = T_MAX;
|
||||
} else {
|
||||
this->m_value *= factor;
|
||||
}
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Operators for multiplication */
|
||||
inline OverflowSafeInt operator * (const int64 factor) const { OverflowSafeInt result = *this; result *= factor; return result; }
|
||||
inline OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
inline OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
inline OverflowSafeInt operator * (const uint16 factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
inline OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
/* Operators for multiplication. */
|
||||
inline constexpr OverflowSafeInt operator * (const int64 factor) const { OverflowSafeInt result = *this; result *= factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const uint16 factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
inline constexpr OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
|
||||
|
||||
/* Operators for division */
|
||||
inline OverflowSafeInt& operator /= (const int64 divisor) { this->m_value /= divisor; return *this; }
|
||||
inline OverflowSafeInt operator / (const OverflowSafeInt& divisor) const { OverflowSafeInt result = *this; result /= divisor.m_value; return result; }
|
||||
inline OverflowSafeInt operator / (const int divisor) const { OverflowSafeInt result = *this; result /= divisor; return result; }
|
||||
inline OverflowSafeInt operator / (const uint divisor) const { OverflowSafeInt result = *this; result /= (int)divisor; return result; }
|
||||
/* Operators for division. */
|
||||
inline constexpr OverflowSafeInt& operator /= (const int64 divisor) { this->m_value /= divisor; return *this; }
|
||||
inline constexpr OverflowSafeInt operator / (const OverflowSafeInt& divisor) const { OverflowSafeInt result = *this; result /= divisor.m_value; return result; }
|
||||
inline constexpr OverflowSafeInt operator / (const int divisor) const { OverflowSafeInt result = *this; result /= divisor; return result; }
|
||||
inline constexpr OverflowSafeInt operator / (const uint divisor) const { OverflowSafeInt result = *this; result /= (int)divisor; return result; }
|
||||
|
||||
/* Operators for modulo */
|
||||
inline OverflowSafeInt& operator %= (const int divisor) { this->m_value %= divisor; return *this; }
|
||||
inline OverflowSafeInt operator % (const int divisor) const { OverflowSafeInt result = *this; result %= divisor; return result; }
|
||||
inline constexpr OverflowSafeInt& operator %= (const int divisor) { this->m_value %= divisor; return *this; }
|
||||
inline constexpr OverflowSafeInt operator % (const int divisor) const { OverflowSafeInt result = *this; result %= divisor; return result; }
|
||||
|
||||
/* Operators for shifting */
|
||||
inline OverflowSafeInt& operator <<= (const int shift) { this->m_value <<= shift; return *this; }
|
||||
inline OverflowSafeInt operator << (const int shift) const { OverflowSafeInt result = *this; result <<= shift; return result; }
|
||||
inline OverflowSafeInt& operator >>= (const int shift) { this->m_value >>= shift; return *this; }
|
||||
inline OverflowSafeInt operator >> (const int shift) const { OverflowSafeInt result = *this; result >>= shift; return result; }
|
||||
/* Operators for shifting. */
|
||||
inline constexpr OverflowSafeInt& operator <<= (const int shift) { this->m_value <<= shift; return *this; }
|
||||
inline constexpr OverflowSafeInt operator << (const int shift) const { OverflowSafeInt result = *this; result <<= shift; return result; }
|
||||
inline constexpr OverflowSafeInt& operator >>= (const int shift) { this->m_value >>= shift; return *this; }
|
||||
inline constexpr OverflowSafeInt operator >> (const int shift) const { OverflowSafeInt result = *this; result >>= shift; return result; }
|
||||
|
||||
/* Operators for (in)equality when comparing overflow safe ints */
|
||||
inline bool operator == (const OverflowSafeInt& other) const { return this->m_value == other.m_value; }
|
||||
inline bool operator != (const OverflowSafeInt& other) const { return !(*this == other); }
|
||||
inline bool operator > (const OverflowSafeInt& other) const { return this->m_value > other.m_value; }
|
||||
inline bool operator >= (const OverflowSafeInt& other) const { return this->m_value >= other.m_value; }
|
||||
inline bool operator < (const OverflowSafeInt& other) const { return !(*this >= other); }
|
||||
inline bool operator <= (const OverflowSafeInt& other) const { return !(*this > other); }
|
||||
/* Operators for (in)equality when comparing overflow safe ints. */
|
||||
inline constexpr bool operator == (const OverflowSafeInt& other) const { return this->m_value == other.m_value; }
|
||||
inline constexpr bool operator != (const OverflowSafeInt& other) const { return !(*this == other); }
|
||||
inline constexpr bool operator > (const OverflowSafeInt& other) const { return this->m_value > other.m_value; }
|
||||
inline constexpr bool operator >= (const OverflowSafeInt& other) const { return this->m_value >= other.m_value; }
|
||||
inline constexpr bool operator < (const OverflowSafeInt& other) const { return !(*this >= other); }
|
||||
inline constexpr bool operator <= (const OverflowSafeInt& other) const { return !(*this > other); }
|
||||
|
||||
/* Operators for (in)equality when comparing non-overflow safe ints */
|
||||
inline bool operator == (const int other) const { return this->m_value == other; }
|
||||
inline bool operator != (const int other) const { return !(*this == other); }
|
||||
inline bool operator > (const int other) const { return this->m_value > other; }
|
||||
inline bool operator >= (const int other) const { return this->m_value >= other; }
|
||||
inline bool operator < (const int other) const { return !(*this >= other); }
|
||||
inline bool operator <= (const int other) const { return !(*this > other); }
|
||||
/* Operators for (in)equality when comparing non-overflow safe ints. */
|
||||
inline constexpr bool operator == (const int other) const { return this->m_value == other; }
|
||||
inline constexpr bool operator != (const int other) const { return !(*this == other); }
|
||||
inline constexpr bool operator > (const int other) const { return this->m_value > other; }
|
||||
inline constexpr bool operator >= (const int other) const { return this->m_value >= other; }
|
||||
inline constexpr bool operator < (const int other) const { return !(*this >= other); }
|
||||
inline constexpr bool operator <= (const int other) const { return !(*this > other); }
|
||||
|
||||
inline operator int64 () const { return this->m_value; }
|
||||
inline constexpr operator int64 () const { return this->m_value; }
|
||||
};
|
||||
|
||||
/* Sometimes we got int64 operator OverflowSafeInt instead of vice versa. Handle that properly */
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
||||
|
||||
/* Sometimes we got int operator OverflowSafeInt instead of vice versa. Handle that properly */
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
||||
/* Sometimes we got int64 operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator + (const int64 a, const OverflowSafeInt<T> b) { return b + a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator - (const int64 a, const OverflowSafeInt<T> b) { return -b + a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator * (const int64 a, const OverflowSafeInt<T> b) { return b * a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const int64 a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||
|
||||
/* Sometimes we got uint operator OverflowSafeInt instead of vice versa. Handle that properly */
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
||||
/* Sometimes we got int operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator + (const int a, const OverflowSafeInt<T> b) { return b + a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator - (const int a, const OverflowSafeInt<T> b) { return -b + a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator * (const int a, const OverflowSafeInt<T> b) { return b * a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const int a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||
|
||||
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly */
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + (uint)a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + (uint)a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * (uint)a; }
|
||||
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
|
||||
/* Sometimes we got uint operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator + (const uint a, const OverflowSafeInt<T> b) { return b + a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator - (const uint a, const OverflowSafeInt<T> b) { return -b + a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator * (const uint a, const OverflowSafeInt<T> b) { return b * a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||
|
||||
typedef OverflowSafeInt<int64, INT64_MAX, INT64_MIN> OverflowSafeInt64;
|
||||
typedef OverflowSafeInt<int32, INT32_MAX, INT32_MIN> OverflowSafeInt32;
|
||||
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly. */
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator + (const byte a, const OverflowSafeInt<T> b) { return b + (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator - (const byte a, const OverflowSafeInt<T> b) { return -b + (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator * (const byte a, const OverflowSafeInt<T> b) { return b * (uint)a; }
|
||||
template <class T> inline constexpr OverflowSafeInt<T> operator / (const byte a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
|
||||
|
||||
typedef OverflowSafeInt<int64> OverflowSafeInt64;
|
||||
typedef OverflowSafeInt<int32> OverflowSafeInt32;
|
||||
|
||||
/* Some basic "unit tests". Also has the bonus of confirming that constexpr is working. */
|
||||
static_assert(OverflowSafeInt32(INT32_MIN) - 1 == OverflowSafeInt32(INT32_MIN));
|
||||
static_assert(OverflowSafeInt32(INT32_MAX) + 1 == OverflowSafeInt32(INT32_MAX));
|
||||
static_assert(OverflowSafeInt32(INT32_MAX) * 2 == OverflowSafeInt32(INT32_MAX));
|
||||
static_assert(OverflowSafeInt32(INT32_MIN) * 2 == OverflowSafeInt32(INT32_MIN));
|
||||
|
||||
#undef HAS_OVERFLOW_BUILTINS
|
||||
|
||||
#endif /* OVERFLOWSAFE_TYPE_HPP */
|
||||
|
||||
@@ -33,9 +33,9 @@ DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
|
||||
first_free(0),
|
||||
first_unused(0),
|
||||
items(0),
|
||||
#ifdef OTTD_ASSERT
|
||||
#ifdef WITH_ASSERT
|
||||
checked(0),
|
||||
#endif /* OTTD_ASSERT */
|
||||
#endif /* WITH_ASSERT */
|
||||
cleaning(false),
|
||||
data(nullptr),
|
||||
alloc_cache(nullptr)
|
||||
@@ -133,10 +133,10 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size)
|
||||
{
|
||||
size_t index = this->FindFirstFree();
|
||||
|
||||
#ifdef OTTD_ASSERT
|
||||
#ifdef WITH_ASSERT
|
||||
assert(this->checked != 0);
|
||||
this->checked--;
|
||||
#endif /* OTTD_ASSERT */
|
||||
#endif /* WITH_ASSERT */
|
||||
if (index == NO_FREE_ITEM) {
|
||||
error("%s: no more free items", this->name);
|
||||
}
|
||||
|
||||
@@ -90,9 +90,9 @@ struct Pool : PoolBase {
|
||||
size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!)
|
||||
size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !)
|
||||
size_t items; ///< Number of used indexes (non-nullptr)
|
||||
#ifdef OTTD_ASSERT
|
||||
#ifdef WITH_ASSERT
|
||||
size_t checked; ///< Number of items we checked for
|
||||
#endif /* OTTD_ASSERT */
|
||||
#endif /* WITH_ASSERT */
|
||||
bool cleaning; ///< True if cleaning pool (deleting all items)
|
||||
|
||||
Titem **data; ///< Pointer to array of pointers to Titem
|
||||
@@ -130,9 +130,9 @@ struct Pool : PoolBase {
|
||||
inline bool CanAllocate(size_t n = 1)
|
||||
{
|
||||
bool ret = this->items <= Tmax_size - n;
|
||||
#ifdef OTTD_ASSERT
|
||||
#ifdef WITH_ASSERT
|
||||
this->checked = ret ? n : 0;
|
||||
#endif /* OTTD_ASSERT */
|
||||
#endif /* WITH_ASSERT */
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,11 @@ struct Pool : PoolBase {
|
||||
|
||||
private:
|
||||
size_t index;
|
||||
void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++; }
|
||||
void ValidateIndex()
|
||||
{
|
||||
while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++;
|
||||
if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -172,7 +176,7 @@ struct Pool : PoolBase {
|
||||
size_t from;
|
||||
IterateWrapper(size_t from = 0) : from(from) {}
|
||||
PoolIterator<T> begin() { return PoolIterator<T>(this->from); }
|
||||
PoolIterator<T> end() { return PoolIterator<T>(T::GetPoolSize()); }
|
||||
PoolIterator<T> end() { return PoolIterator<T>(T::Pool::MAX_SIZE); }
|
||||
bool empty() { return this->begin() == this->end(); }
|
||||
};
|
||||
|
||||
@@ -201,7 +205,11 @@ struct Pool : PoolBase {
|
||||
private:
|
||||
size_t index;
|
||||
F filter;
|
||||
void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++; }
|
||||
void ValidateIndex()
|
||||
{
|
||||
while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++;
|
||||
if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -214,7 +222,7 @@ struct Pool : PoolBase {
|
||||
F filter;
|
||||
IterateWrapperFiltered(size_t from, F filter) : from(from), filter(filter) {}
|
||||
PoolIteratorFiltered<T, F> begin() { return PoolIteratorFiltered<T, F>(this->from, this->filter); }
|
||||
PoolIteratorFiltered<T, F> end() { return PoolIteratorFiltered<T, F>(T::GetPoolSize(), this->filter); }
|
||||
PoolIteratorFiltered<T, F> end() { return PoolIteratorFiltered<T, F>(T::Pool::MAX_SIZE, this->filter); }
|
||||
bool empty() { return this->begin() == this->end(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ void SetRandomSeed(uint32 seed)
|
||||
uint32 DoRandom(int line, const char *file)
|
||||
{
|
||||
if (_networking && (!_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != NetworkClientSocket::STATUS_INACTIVE))) {
|
||||
DEBUG(random, 0, "%08x; %02x; %04x; %02x; %s:%d", _date, _date_fract, _frame_counter, (byte)_current_company, file, line);
|
||||
Debug(random, 0, "{:08x}; {:02x}; {:04x}; {:02x}; {}:{}", _date, _date_fract, _frame_counter, (byte)_current_company, file, line);
|
||||
}
|
||||
|
||||
return _random.Next();
|
||||
|
||||
100
src/core/span_type.hpp
Normal file
100
src/core/span_type.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file span_type.hpp Minimized implementation of C++20 std::span. */
|
||||
|
||||
#ifndef CORE_SPAN_TYPE_HPP
|
||||
#define CORE_SPAN_TYPE_HPP
|
||||
|
||||
/* This is a partial copy/paste from https://github.com/gsl-lite/gsl-lite/blob/master/include/gsl/gsl-lite.hpp */
|
||||
|
||||
/* Template to check if a template variable defines size() and data(). */
|
||||
template <class, class = void>
|
||||
struct has_size_and_data : std::false_type{};
|
||||
template <class C>
|
||||
struct has_size_and_data
|
||||
<
|
||||
C, std::void_t<
|
||||
decltype(std::size(std::declval<C>())),
|
||||
decltype(std::data(std::declval<C>()))>
|
||||
> : std::true_type{};
|
||||
|
||||
/* Template to check if two elements are compatible. */
|
||||
template <class, class, class = void>
|
||||
struct is_compatible_element : std::false_type {};
|
||||
template <class C, class E>
|
||||
struct is_compatible_element
|
||||
<
|
||||
C, E, std::void_t<
|
||||
decltype(std::data(std::declval<C>())),
|
||||
typename std::remove_pointer<decltype(std::data( std::declval<C&>()))>::type(*)[]>
|
||||
> : std::is_convertible<typename std::remove_pointer<decltype(std::data(std::declval<C&>()))>::type(*)[], E(*)[]>{};
|
||||
|
||||
/* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */
|
||||
template <class C, class E>
|
||||
struct is_compatible_container : std::bool_constant
|
||||
<
|
||||
has_size_and_data<C>::value
|
||||
&& is_compatible_element<C,E>::value
|
||||
>{};
|
||||
|
||||
/**
|
||||
* A trimmed down version of what std::span will be in C++20.
|
||||
*
|
||||
* It is fully forwards compatible, so if this codebase switches to C++20,
|
||||
* all "span" instances can be replaced by "std::span" without loss of
|
||||
* functionality.
|
||||
*
|
||||
* Currently it only supports basic functionality:
|
||||
* - size() and friends
|
||||
* - begin() and friends
|
||||
*
|
||||
* It is meant to simplify function parameters, where we only want to walk
|
||||
* a continuous list.
|
||||
*/
|
||||
template<class T>
|
||||
class span {
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef typename std::remove_cv< T >::type value_type;
|
||||
|
||||
typedef T &reference;
|
||||
typedef T *pointer;
|
||||
typedef const T &const_reference;
|
||||
typedef const T *const_pointer;
|
||||
|
||||
typedef pointer iterator;
|
||||
typedef const_pointer const_iterator;
|
||||
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
constexpr span() noexcept : first(nullptr), last(nullptr) {}
|
||||
|
||||
constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {}
|
||||
|
||||
template<class Container, typename std::enable_if<(is_compatible_container<Container, element_type>::value), int>::type = 0>
|
||||
constexpr span(Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
|
||||
template<class Container, typename std::enable_if<(std::is_const<element_type>::value && is_compatible_container<Container, element_type>::value), int>::type = 0>
|
||||
constexpr span(const Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
|
||||
|
||||
constexpr size_t size() const noexcept { return static_cast<size_t>( last - first ); }
|
||||
constexpr std::ptrdiff_t ssize() const noexcept { return static_cast<std::ptrdiff_t>( last - first ); }
|
||||
constexpr bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
constexpr iterator begin() const noexcept { return iterator(first); }
|
||||
constexpr iterator end() const noexcept { return iterator(last); }
|
||||
|
||||
constexpr const_iterator cbegin() const noexcept { return const_iterator(first); }
|
||||
constexpr const_iterator cend() const noexcept { return const_iterator(last); }
|
||||
|
||||
private:
|
||||
pointer first;
|
||||
pointer last;
|
||||
};
|
||||
|
||||
#endif /* CORE_SPAN_TYPE_HPP */
|
||||
@@ -32,8 +32,7 @@
|
||||
#include "game/game_info.hpp"
|
||||
#include "company_base.h"
|
||||
#include "company_func.h"
|
||||
|
||||
#include <time.h>
|
||||
#include "walltime_func.h"
|
||||
|
||||
#ifdef WITH_ALLEGRO
|
||||
# include <allegro.h>
|
||||
@@ -127,7 +126,7 @@ char *CrashLog::LogOpenTTDVersion(char *buffer, const char *last) const
|
||||
_openttd_revision,
|
||||
_openttd_revision_modified,
|
||||
_openttd_newgrf_version,
|
||||
#ifdef _SQ64
|
||||
#ifdef POINTER_IS_64BIT
|
||||
64,
|
||||
#else
|
||||
32,
|
||||
@@ -333,9 +332,8 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const
|
||||
*/
|
||||
char *CrashLog::FillCrashLog(char *buffer, const char *last) const
|
||||
{
|
||||
time_t cur_time = time(nullptr);
|
||||
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
|
||||
buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time)));
|
||||
buffer += UTCTime::Format(buffer, last, "Crash at: %Y-%m-%d %H:%M:%S (UTC)\n");
|
||||
|
||||
YearMonthDay ymd;
|
||||
ConvertDateToYMD(_date, &ymd);
|
||||
|
||||
@@ -70,11 +70,11 @@ enum Currencies {
|
||||
|
||||
/** Specification of a currency. */
|
||||
struct CurrencySpec {
|
||||
uint16 rate;
|
||||
char separator[8];
|
||||
Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
|
||||
char prefix[16];
|
||||
char suffix[16];
|
||||
uint16 rate; ///< The conversion rate compared to the base currency.
|
||||
std::string separator; ///< The thousands separator for this currency.
|
||||
Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
|
||||
std::string prefix; ///< Prefix to apply when formatting money in this currency.
|
||||
std::string suffix; ///< Suffix to apply when formatting money in this currency.
|
||||
/**
|
||||
* The currency symbol is represented by two possible values, prefix and suffix
|
||||
* Usage of one or the other is determined by #symbol_pos.
|
||||
@@ -89,11 +89,9 @@ struct CurrencySpec {
|
||||
|
||||
CurrencySpec() = default;
|
||||
|
||||
CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) : rate(rate), to_euro(to_euro), symbol_pos(symbol_pos), name(name)
|
||||
CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) :
|
||||
rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), symbol_pos(symbol_pos), name(name)
|
||||
{
|
||||
strecpy(this->separator, separator, lastof(this->separator));
|
||||
strecpy(this->prefix, prefix, lastof(this->prefix));
|
||||
strecpy(this->suffix, suffix, lastof(this->suffix));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ struct SetDateWindow : Window {
|
||||
|
||||
case WID_SD_SET_DATE:
|
||||
if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day));
|
||||
delete this;
|
||||
this->Close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -212,6 +212,6 @@ static WindowDesc _set_date_desc(
|
||||
*/
|
||||
void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback)
|
||||
{
|
||||
DeleteWindowByClass(WC_SET_DATE);
|
||||
CloseWindowByClass(WC_SET_DATE);
|
||||
new SetDateWindow(&_set_date_desc, window_number, parent, initial_date, min_year, max_year, callback);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef uint8 Day; ///< Type for the day of the month, note: 1 based, first d
|
||||
static const int DAY_TICKS = 74; ///< ticks per day
|
||||
static const int DAYS_IN_YEAR = 365; ///< days per year
|
||||
static const int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more...
|
||||
static const int MONTHS_IN_YEAR = 12; ///< months per year
|
||||
|
||||
static const int STATION_RATING_TICKS = 185; ///< cycle duration for updating station rating
|
||||
static const int STATION_ACCEPTANCE_TICKS = 250; ///< cycle duration for updating station acceptance
|
||||
|
||||
121
src/debug.cpp
121
src/debug.cpp
@@ -14,6 +14,8 @@
|
||||
#include "string_func.h"
|
||||
#include "fileio_func.h"
|
||||
#include "settings_type.h"
|
||||
#include <mutex>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
@@ -22,13 +24,23 @@
|
||||
#include "os/windows/win32.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include "walltime_func.h"
|
||||
|
||||
#include "network/network_admin.h"
|
||||
SOCKET _debug_socket = INVALID_SOCKET;
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
/** Element in the queue of debug messages that have to be passed to either NetworkAdminConsole or IConsolePrint.*/
|
||||
struct QueuedDebugItem {
|
||||
std::string level; ///< The used debug level.
|
||||
std::string message; ///< The actual formatted message.
|
||||
};
|
||||
std::atomic<bool> _debug_remote_console; ///< Whether we need to send data to either NetworkAdminConsole or IConsolePrint.
|
||||
std::mutex _debug_remote_console_mutex; ///< Mutex to guard the queue of debug messages for either NetworkAdminConsole or IConsolePrint.
|
||||
std::vector<QueuedDebugItem> _debug_remote_console_queue; ///< Queue for debug messages to be passed to NetworkAdminConsole or IConsolePrint.
|
||||
std::vector<QueuedDebugItem> _debug_remote_console_queue_spare; ///< Spare queue to swap with _debug_remote_console_queue.
|
||||
|
||||
int _debug_driver_level;
|
||||
int _debug_grf_level;
|
||||
int _debug_map_level;
|
||||
@@ -103,70 +115,52 @@ char *DumpDebugFacilityNames(char *buf, char *last)
|
||||
|
||||
/**
|
||||
* Internal function for outputting the debug line.
|
||||
* @param dbg Debug category.
|
||||
* @param buf Text line to output.
|
||||
* @param level Debug category.
|
||||
* @param message The message to output.
|
||||
*/
|
||||
static void debug_print(const char *dbg, const char *buf)
|
||||
void DebugPrint(const char *level, const std::string &message)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, "OpenTTD", "[%s] %s", dbg, buf);
|
||||
#endif
|
||||
if (_debug_socket != INVALID_SOCKET) {
|
||||
char buf2[1024 + 32];
|
||||
std::string msg = fmt::format("{}dbg: [{}] {}\n", GetLogPrefix(), level, message);
|
||||
|
||||
/* Prevent sending a message concurrently, as that might cause interleaved messages. */
|
||||
static std::mutex _debug_socket_mutex;
|
||||
std::lock_guard<std::mutex> lock(_debug_socket_mutex);
|
||||
|
||||
seprintf(buf2, lastof(buf2), "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf);
|
||||
/* Sending out an error when this fails would be nice, however... the error
|
||||
* would have to be send over this failing socket which won't work. */
|
||||
send(_debug_socket, buf2, (int)strlen(buf2), 0);
|
||||
send(_debug_socket, msg.c_str(), (int)msg.size(), 0);
|
||||
return;
|
||||
}
|
||||
if (strcmp(dbg, "desync") == 0) {
|
||||
if (strcmp(level, "desync") == 0) {
|
||||
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
|
||||
if (f == nullptr) return;
|
||||
|
||||
fprintf(f, "%s%s\n", GetLogPrefix(), buf);
|
||||
fprintf(f, "%s%s\n", GetLogPrefix(), message.c_str());
|
||||
fflush(f);
|
||||
#ifdef RANDOM_DEBUG
|
||||
} else if (strcmp(dbg, "random") == 0) {
|
||||
} else if (strcmp(level, "random") == 0) {
|
||||
static FILE *f = FioFOpenFile("random-out.log", "wb", AUTOSAVE_DIR);
|
||||
if (f == nullptr) return;
|
||||
|
||||
fprintf(f, "%s\n", buf);
|
||||
fprintf(f, "%s\n", message.c_str());
|
||||
fflush(f);
|
||||
#endif
|
||||
} else {
|
||||
char buffer[512];
|
||||
seprintf(buffer, lastof(buffer), "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf);
|
||||
#if defined(_WIN32)
|
||||
wchar_t system_buf[512];
|
||||
convert_to_fs(buffer, system_buf, lengthof(system_buf));
|
||||
fputws(system_buf, stderr);
|
||||
#else
|
||||
fputs(buffer, stderr);
|
||||
#endif
|
||||
NetworkAdminConsole(dbg, buf);
|
||||
IConsoleDebug(dbg, buf);
|
||||
std::string msg = fmt::format("{}dbg: [{}] {}\n", GetLogPrefix(), level, message);
|
||||
fputs(msg.c_str(), stderr);
|
||||
|
||||
if (_debug_remote_console.load()) {
|
||||
/* Only add to the queue when there is at least one consumer of the data. */
|
||||
std::lock_guard<std::mutex> lock(_debug_remote_console_mutex);
|
||||
_debug_remote_console_queue.push_back({ level, message });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a debug line.
|
||||
* @note Do not call directly, use the #DEBUG macro instead.
|
||||
* @param dbg Debug category.
|
||||
* @param format Text string a la printf, with optional arguments.
|
||||
*/
|
||||
void CDECL debug(const char *dbg, const char *format, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
vseprintf(buf, lastof(buf), format, va);
|
||||
va_end(va);
|
||||
|
||||
debug_print(dbg, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set debugging levels by parsing the text in \a s.
|
||||
* For setting individual levels a string like \c "net=3,grf=6" should be used.
|
||||
@@ -254,11 +248,54 @@ const char *GetLogPrefix()
|
||||
{
|
||||
static char _log_prefix[24];
|
||||
if (_settings_client.gui.show_date_in_logs) {
|
||||
time_t cur_time = time(nullptr);
|
||||
strftime(_log_prefix, sizeof(_log_prefix), "[%Y-%m-%d %H:%M:%S] ", localtime(&cur_time));
|
||||
LocalTime::Format(_log_prefix, lastof(_log_prefix), "[%Y-%m-%d %H:%M:%S] ");
|
||||
} else {
|
||||
*_log_prefix = '\0';
|
||||
}
|
||||
return _log_prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the queued Debug messages to either NetworkAdminConsole or IConsolePrint from the
|
||||
* GameLoop thread to prevent concurrent accesses to both the NetworkAdmin's packet queue
|
||||
* as well as IConsolePrint's buffers.
|
||||
*
|
||||
* This is to be called from the GameLoop thread.
|
||||
*/
|
||||
void DebugSendRemoteMessages()
|
||||
{
|
||||
if (!_debug_remote_console.load()) return;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_debug_remote_console_mutex);
|
||||
std::swap(_debug_remote_console_queue, _debug_remote_console_queue_spare);
|
||||
}
|
||||
|
||||
for (auto &item : _debug_remote_console_queue_spare) {
|
||||
NetworkAdminConsole(item.level, item.message);
|
||||
if (_settings_client.gui.developer >= 2) IConsolePrint(CC_DEBUG, "dbg: [{}] {}", item.level, item.message);
|
||||
}
|
||||
|
||||
_debug_remote_console_queue_spare.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconsider whether we need to send debug messages to either NetworkAdminConsole
|
||||
* or IConsolePrint. The former is when they have enabled console handling whereas
|
||||
* the latter depends on the gui.developer setting's value.
|
||||
*
|
||||
* This is to be called from the GameLoop thread.
|
||||
*/
|
||||
void DebugReconsiderSendRemoteMessages()
|
||||
{
|
||||
bool enable = _settings_client.gui.developer >= 2;
|
||||
|
||||
for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
|
||||
if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
|
||||
enable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_debug_remote_console.store(enable);
|
||||
}
|
||||
|
||||
22
src/debug.h
22
src/debug.h
@@ -12,9 +12,10 @@
|
||||
|
||||
#include "cpu.h"
|
||||
#include <chrono>
|
||||
#include "3rdparty/fmt/format.h"
|
||||
|
||||
/* Debugging messages policy:
|
||||
* These should be the severities used for direct DEBUG() calls
|
||||
* These should be the severities used for direct Debug() calls
|
||||
* maximum debugging level should be 10 if really deep, deep
|
||||
* debugging is needed.
|
||||
* (there is room for exceptions, but you have to have a good cause):
|
||||
@@ -28,11 +29,13 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Output a line of debugging information.
|
||||
* @param name Category
|
||||
* @param level Debugging level, higher levels means more detailed information.
|
||||
* Ouptut a line of debugging information.
|
||||
* @param name The category of debug information.
|
||||
* @param level The maximum debug level this message should be shown at. When the debug level for this category is set lower, then the message will not be shown.
|
||||
* @param format_string The formatting string of the message.
|
||||
*/
|
||||
#define DEBUG(name, level, ...) if ((level) == 0 || _debug_ ## name ## _level >= (level)) debug(#name, __VA_ARGS__)
|
||||
#define Debug(name, level, format_string, ...) if ((level) == 0 || _debug_ ## name ## _level >= (level)) DebugPrint(#name, fmt::format(FMT_STRING(format_string), ## __VA_ARGS__))
|
||||
void DebugPrint(const char *level, const std::string &message);
|
||||
|
||||
extern int _debug_driver_level;
|
||||
extern int _debug_grf_level;
|
||||
@@ -53,8 +56,6 @@ extern int _debug_console_level;
|
||||
extern int _debug_random_level;
|
||||
#endif
|
||||
|
||||
void CDECL debug(const char *dbg, const char *format, ...) WARN_FORMAT(2, 3);
|
||||
|
||||
char *DumpDebugFacilityNames(char *buf, char *last);
|
||||
void SetDebugString(const char *s);
|
||||
const char *GetDebugString();
|
||||
@@ -94,7 +95,7 @@ const char *GetDebugString();
|
||||
#define TOC(str, count)\
|
||||
_sum_ += ottd_rdtsc() - _xxx_;\
|
||||
if (++_i_ == count) {\
|
||||
DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " [avg: %.1f]", str, _sum_, _sum_/(double)_i_);\
|
||||
Debug(misc, 0, "[{}] {} [avg: {:.1f}]", str, _sum_, _sum_/(double)_i_);\
|
||||
_i_ = 0;\
|
||||
_sum_ = 0;\
|
||||
}\
|
||||
@@ -109,7 +110,7 @@ const char *GetDebugString();
|
||||
#define TOCC(str, _count_)\
|
||||
_sum_ += (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - _start_)).count();\
|
||||
if (++_i_ == _count_) {\
|
||||
DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " us [avg: %.1f us]", str, _sum_, _sum_/(double)_i_);\
|
||||
Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", str, _sum_, _sum_/(double)_i_);\
|
||||
_i_ = 0;\
|
||||
_sum_ = 0;\
|
||||
}\
|
||||
@@ -121,4 +122,7 @@ void CDECL ShowInfoF(const char *str, ...) WARN_FORMAT(1, 2);
|
||||
|
||||
const char *GetLogPrefix();
|
||||
|
||||
void DebugSendRemoteMessages();
|
||||
void DebugReconsiderSendRemoteMessages();
|
||||
|
||||
#endif /* DEBUG_H */
|
||||
|
||||
@@ -41,9 +41,9 @@ Depot::~Depot()
|
||||
RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->index);
|
||||
|
||||
/* Delete the depot-window */
|
||||
DeleteWindowById(WC_VEHICLE_DEPOT, this->xy);
|
||||
CloseWindowById(WC_VEHICLE_DEPOT, this->xy);
|
||||
|
||||
/* Delete the depot list */
|
||||
VehicleType vt = GetDepotVehicleType(this->xy);
|
||||
DeleteWindowById(GetWindowClassForVehicleType(vt), VehicleListIdentifier(VL_DEPOT_LIST, vt, GetTileOwner(this->xy), this->index).Pack());
|
||||
CloseWindowById(GetWindowClassForVehicleType(vt), VehicleListIdentifier(VL_DEPOT_LIST, vt, GetTileOwner(this->xy), this->index).Pack());
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* @param name The name to check.
|
||||
* @return True if there is no depot with the given name.
|
||||
*/
|
||||
static bool IsUniqueDepotName(const char *name)
|
||||
static bool IsUniqueDepotName(const std::string &name)
|
||||
{
|
||||
for (const Depot *d : Depot::Iterate()) {
|
||||
if (!d->name.empty() && d->name == name) return false;
|
||||
@@ -44,7 +44,7 @@ static bool IsUniqueDepotName(const char *name)
|
||||
* @param text the new name or an empty string when resetting to the default
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
Depot *d = Depot::GetIfValid(p1);
|
||||
if (d == nullptr) return CMD_ERROR;
|
||||
@@ -52,7 +52,7 @@ CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
||||
CommandCost ret = CheckTileOwnership(d->xy);
|
||||
if (ret.Failed()) return ret;
|
||||
|
||||
bool reset = StrEmpty(text);
|
||||
bool reset = text.empty();
|
||||
|
||||
if (!reset) {
|
||||
if (Utf8StringLength(text) >= MAX_LENGTH_DEPOT_NAME_CHARS) return CMD_ERROR;
|
||||
|
||||
@@ -291,11 +291,12 @@ struct DepotWindow : Window {
|
||||
OrderBackup::Reset();
|
||||
}
|
||||
|
||||
~DepotWindow()
|
||||
void Close() override
|
||||
{
|
||||
DeleteWindowById(WC_BUILD_VEHICLE, this->window_number);
|
||||
DeleteWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VL_DEPOT_LIST, this->type, this->owner, this->GetDepotIndex()).Pack(), false);
|
||||
CloseWindowById(WC_BUILD_VEHICLE, this->window_number);
|
||||
CloseWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VL_DEPOT_LIST, this->type, this->owner, this->GetDepotIndex()).Pack(), false);
|
||||
OrderBackup::Reset(this->window_number);
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,11 +398,11 @@ struct DepotWindow : Window {
|
||||
|
||||
uint16 rows_in_display = wid->current_y / wid->resize_y;
|
||||
|
||||
uint16 num = this->vscroll->GetPosition() * this->num_columns;
|
||||
uint num = this->vscroll->GetPosition() * this->num_columns;
|
||||
uint maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size(), num + (rows_in_display * this->num_columns)));
|
||||
int y;
|
||||
for (y = r.top; num < maxval; y += this->resize.step_height) { // Draw the rows
|
||||
for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) {
|
||||
for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows
|
||||
for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
|
||||
/* Draw all vehicles in the current row */
|
||||
const Vehicle *v = this->vehicle_list[num];
|
||||
if (this->num_columns == 1) {
|
||||
@@ -1048,7 +1049,7 @@ struct DepotWindow : Window {
|
||||
this->RaiseWidget(WID_D_SELL);
|
||||
this->SetWidgetDirty(WID_D_SELL);
|
||||
}
|
||||
if (this->nested_array[WID_D_SELL] != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) {
|
||||
if (this->GetWidget<NWidgetBase>(WID_D_SELL) != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) {
|
||||
this->RaiseWidget(WID_D_SELL_CHAIN);
|
||||
this->SetWidgetDirty(WID_D_SELL_CHAIN);
|
||||
}
|
||||
|
||||
@@ -102,11 +102,12 @@ struct BuildDocksToolbarWindow : Window {
|
||||
if (_settings_client.gui.link_terraform_toolbar || _settings_client.gui.compact_vertical_toolbar) ShowTerraformToolbar();
|
||||
}
|
||||
|
||||
~BuildDocksToolbarWindow()
|
||||
void Close() override
|
||||
{
|
||||
if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort();
|
||||
if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_DT_STATION)) SetViewportCatchmentStation(nullptr, true);
|
||||
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
|
||||
if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false);
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,8 +126,8 @@ struct BuildDocksToolbarWindow : Window {
|
||||
WID_DT_BUOY,
|
||||
WIDGET_LIST_END);
|
||||
if (!can_build) {
|
||||
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
|
||||
DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
|
||||
CloseWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
|
||||
CloseWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
|
||||
}
|
||||
|
||||
if (_game_mode != GM_EDITOR) {
|
||||
@@ -301,9 +302,10 @@ struct BuildDocksToolbarWindow : Window {
|
||||
this->RaiseButtons();
|
||||
|
||||
if (ConfirmationWindowShown() && _ctrl_pressed) return;
|
||||
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
|
||||
DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
|
||||
DeleteWindowById(WC_SELECT_STATION, 0);
|
||||
CloseWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
|
||||
CloseWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
|
||||
CloseWindowById(WC_SELECT_STATION, 0);
|
||||
CloseWindowByClass(WC_BUILD_BRIDGE);
|
||||
}
|
||||
|
||||
void SelectLastTool() override
|
||||
@@ -408,7 +410,7 @@ Window *ShowBuildDocksToolbar()
|
||||
{
|
||||
if (!Company::IsValidID(_local_company)) return nullptr;
|
||||
|
||||
DeleteToolbarLinkedWindows();
|
||||
CloseToolbarLinkedWindows();
|
||||
return AllocateWindowDescFront<BuildDocksToolbarWindow>(&_build_docks_toolbar_desc, TRANSPORT_WATER);
|
||||
}
|
||||
|
||||
@@ -447,7 +449,7 @@ static WindowDesc _build_docks_scen_toolbar_desc(
|
||||
*/
|
||||
Window *ShowBuildDocksScenToolbar()
|
||||
{
|
||||
DeleteToolbarLinkedWindows();
|
||||
CloseToolbarLinkedWindows();
|
||||
return AllocateWindowDescFront<BuildDocksToolbarWindow>(&_build_docks_scen_toolbar_desc, TRANSPORT_WATER);
|
||||
}
|
||||
|
||||
@@ -467,9 +469,10 @@ public:
|
||||
this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF);
|
||||
}
|
||||
|
||||
virtual ~BuildDocksStationWindow()
|
||||
void Close() override
|
||||
{
|
||||
DeleteWindowById(WC_SELECT_STATION, 0);
|
||||
CloseWindowById(WC_SELECT_STATION, 0);
|
||||
this->PickerWindowBase::Close();
|
||||
}
|
||||
|
||||
void OnPaint() override
|
||||
|
||||
@@ -121,13 +121,13 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
|
||||
|
||||
const char *err = newd->Start({});
|
||||
if (err == nullptr) {
|
||||
DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
|
||||
Debug(driver, 1, "Successfully probed {} driver '{}'", GetDriverTypeName(type), d->name);
|
||||
delete oldd;
|
||||
return true;
|
||||
}
|
||||
|
||||
*GetActiveDriver(type) = oldd;
|
||||
DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
|
||||
Debug(driver, 1, "Probing {} driver '{}' failed with error: {}", GetDriverTypeName(type), d->name, err);
|
||||
delete newd;
|
||||
|
||||
if (type == Driver::DT_VIDEO && _video_hw_accel && d->UsesHardwareAcceleration()) {
|
||||
@@ -170,7 +170,7 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
|
||||
usererror("Unable to load driver '%s'. The error was: %s", d->name, err);
|
||||
}
|
||||
|
||||
DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name);
|
||||
Debug(driver, 1, "Successfully loaded {} driver '{}'", GetDriverTypeName(type), d->name);
|
||||
delete *GetActiveDriver(type);
|
||||
*GetActiveDriver(type) = newd;
|
||||
return true;
|
||||
|
||||
@@ -311,7 +311,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (c->share_owners[i] == old_owner) {
|
||||
/* Sell his shares */
|
||||
/* Sell its shares */
|
||||
CommandCost res = DoCommand(0, c->index, 0, DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY);
|
||||
/* Because we are in a DoCommand, we can't just execute another one and
|
||||
* expect the money to be removed. We need to do it ourself! */
|
||||
@@ -324,8 +324,13 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
|
||||
Backup<CompanyID> cur_company2(_current_company, FILE_LINE);
|
||||
const Company *c = Company::Get(old_owner);
|
||||
for (i = 0; i < 4; i++) {
|
||||
cur_company2.Change(c->share_owners[i]);
|
||||
if (_current_company != INVALID_OWNER) {
|
||||
if (c->share_owners[i] == INVALID_OWNER) continue;
|
||||
|
||||
if (c->bankrupt_value == 0 && c->share_owners[i] == new_owner) {
|
||||
/* You are the one buying the company; so don't sell the shares back to you. */
|
||||
Company::Get(new_owner)->share_owners[i] = INVALID_OWNER;
|
||||
} else {
|
||||
cur_company2.Change(c->share_owners[i]);
|
||||
/* Sell the shares */
|
||||
CommandCost res = DoCommand(0, old_owner, 0, DC_EXEC | DC_BANKRUPT, CMD_SELL_SHARE_IN_COMPANY);
|
||||
/* Because we are in a DoCommand, we can't just execute another one and
|
||||
@@ -337,7 +342,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
|
||||
}
|
||||
|
||||
/* Temporarily increase the company's money, to be sure that
|
||||
* removing his/her property doesn't fail because of lack of money.
|
||||
* removing their property doesn't fail because of lack of money.
|
||||
* Not too drastically though, because it could overflow */
|
||||
if (new_owner == INVALID_OWNER) {
|
||||
Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p
|
||||
@@ -575,8 +580,7 @@ static void CompanyCheckBankrupt(Company *c)
|
||||
|
||||
/* Warn about bankruptcy after 3 months */
|
||||
case 4: {
|
||||
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
|
||||
cni->FillData(c);
|
||||
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
|
||||
SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE);
|
||||
SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION);
|
||||
SetDParamStr(2, cni->company_name);
|
||||
@@ -607,7 +611,7 @@ static void CompanyCheckBankrupt(Company *c)
|
||||
if (!_networking && _local_company == c->index) {
|
||||
/* If we are in singleplayer mode, leave the company playing. Eg. there
|
||||
* is no THE-END, otherwise mark the client as spectator to make sure
|
||||
* he/she is no long in control of this company. However... when you
|
||||
* they are no longer in control of this company. However... when you
|
||||
* join another company (cheat) the "unowned" company can bankrupt. */
|
||||
c->bankrupt_asked = MAX_UVALUE(CompanyMask);
|
||||
break;
|
||||
@@ -799,7 +803,7 @@ void RecomputePrices()
|
||||
|
||||
/* Setup cargo payment */
|
||||
for (CargoSpec *cs : CargoSpec::Iterate()) {
|
||||
cs->current_payment = ((int64)cs->initial_payment * _economy.inflation_payment) >> 16;
|
||||
cs->current_payment = (cs->initial_payment * (int64)_economy.inflation_payment) >> 16;
|
||||
}
|
||||
|
||||
SetWindowClassesDirty(WC_BUILD_VEHICLE);
|
||||
@@ -1476,9 +1480,8 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
|
||||
bool is_auto_refit = new_cid == CT_AUTO_REFIT;
|
||||
if (is_auto_refit) {
|
||||
/* Get a refittable cargo type with waiting cargo for next_station or INVALID_STATION. */
|
||||
CargoID cid;
|
||||
new_cid = v_start->cargo_type;
|
||||
FOR_EACH_SET_CARGO_ID(cid, refit_mask) {
|
||||
for (CargoID cid : SetCargoBitIterator(refit_mask)) {
|
||||
if (st->goods[cid].cargo.HasCargoFor(next_station)) {
|
||||
/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
|
||||
* the returned refit capacity will be greater than zero. */
|
||||
@@ -1970,8 +1973,7 @@ static void DoAcquireCompany(Company *c)
|
||||
{
|
||||
CompanyID ci = c->index;
|
||||
|
||||
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
|
||||
cni->FillData(c, Company::Get(_current_company));
|
||||
CompanyNewsInformation *cni = new CompanyNewsInformation(c, Company::Get(_current_company));
|
||||
|
||||
SetDParam(0, STR_NEWS_COMPANY_MERGER_TITLE);
|
||||
SetDParam(1, c->bankrupt_value == 0 ? STR_NEWS_MERGER_TAKEOVER_TITLE : STR_NEWS_COMPANY_MERGER_DESCRIPTION);
|
||||
@@ -1986,12 +1988,15 @@ static void DoAcquireCompany(Company *c)
|
||||
|
||||
if (c->bankrupt_value == 0) {
|
||||
Company *owner = Company::Get(_current_company);
|
||||
|
||||
/* Get both the balance and the loan of the company you just bought. */
|
||||
SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -c->money));
|
||||
owner->current_loan += c->current_loan;
|
||||
}
|
||||
|
||||
if (c->is_ai) AI::Stop(c->index);
|
||||
|
||||
DeleteCompanyWindows(ci);
|
||||
CloseCompanyWindows(ci);
|
||||
InvalidateWindowClassesData(WC_TRAINS_LIST, 0);
|
||||
InvalidateWindowClassesData(WC_SHIPS_LIST, 0);
|
||||
InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
|
||||
@@ -2011,7 +2016,7 @@ extern int GetAmountOwnedBy(const Company *c, Owner owner);
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
CommandCost cost(EXPENSES_OTHER);
|
||||
CompanyID target_company = (CompanyID)p1;
|
||||
@@ -2063,7 +2068,7 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
CompanyID target_company = (CompanyID)p1;
|
||||
Company *c = Company::GetIfValid(target_company);
|
||||
@@ -2104,7 +2109,7 @@ CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
CompanyID target_company = (CompanyID)p1;
|
||||
Company *c = Company::GetIfValid(target_company);
|
||||
|
||||
@@ -34,7 +34,7 @@ struct Economy {
|
||||
uint32 industry_daily_change_counter; ///< Bits 31-16 are number of industry to be performed, 15-0 are fractional collected daily
|
||||
uint32 industry_daily_increment; ///< The value which will increment industry_daily_change_counter. Computed value. NOSAVE
|
||||
uint64 inflation_prices; ///< Cumulated inflation of prices since game start; 16 bit fractional part
|
||||
uint64 inflation_payment; ///< Cumulated inflation of cargo paypent since game start; 16 bit fractional part
|
||||
uint64 inflation_payment; ///< Cumulated inflation of cargo payment since game start; 16 bit fractional part
|
||||
|
||||
/* Old stuff for savegame conversion only */
|
||||
Money old_max_loan_unround; ///< Old: Unrounded max loan
|
||||
|
||||
@@ -470,8 +470,7 @@ static void DrawRailCatenaryRailway(const TileInfo *ti)
|
||||
}
|
||||
|
||||
/* Drawing of pylons is finished, now draw the wires */
|
||||
Track t;
|
||||
FOR_EACH_SET_TRACK(t, wireconfig[TS_HOME]) {
|
||||
for (Track t : SetTrackBitIterator(wireconfig[TS_HOME])) {
|
||||
SpriteID wire_base = (t == halftile_track) ? wire_halftile : wire_normal;
|
||||
byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) +
|
||||
(HasBit(PCPstatus, PCPpositions[t][1]) << 1);
|
||||
@@ -593,9 +592,9 @@ void DrawRailCatenary(const TileInfo *ti)
|
||||
DrawRailCatenaryRailway(ti);
|
||||
}
|
||||
|
||||
bool SettingsDisableElrail(int32 p1)
|
||||
void SettingsDisableElrail(int32 new_value)
|
||||
{
|
||||
bool disable = (p1 != 0);
|
||||
bool disable = (new_value != 0);
|
||||
|
||||
/* we will now walk through all electric train engines and change their railtypes if it is the wrong one*/
|
||||
const RailType old_railtype = disable ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL;
|
||||
@@ -639,5 +638,4 @@ bool SettingsDisableElrail(int32 p1)
|
||||
* rails. It may have unintended consequences if that function is ever
|
||||
* extended, though. */
|
||||
ReinitGuiAfterToggleElrail(disable);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,6 @@ void DrawRailCatenary(const TileInfo *ti);
|
||||
void DrawRailCatenaryOnTunnel(const TileInfo *ti);
|
||||
void DrawRailCatenaryOnBridge(const TileInfo *ti);
|
||||
|
||||
bool SettingsDisableElrail(int32 p1); ///< _settings_game.disable_elrail callback
|
||||
void SettingsDisableElrail(int32 new_value); ///< _settings_game.disable_elrail callback
|
||||
|
||||
#endif /* ELRAIL_FUNC_H */
|
||||
|
||||
@@ -528,7 +528,7 @@ bool EngineOverrideManager::ResetToCurrentNewGRFConfig()
|
||||
*/
|
||||
void SetupEngines()
|
||||
{
|
||||
DeleteWindowByClass(WC_ENGINE_PREVIEW);
|
||||
CloseWindowByClass(WC_ENGINE_PREVIEW);
|
||||
_engine_pool.CleanPool();
|
||||
|
||||
assert(_engine_mngr.size() >= _engine_mngr.NUM_DEFAULT_ENGINES);
|
||||
@@ -537,8 +537,7 @@ void SetupEngines()
|
||||
/* Assert is safe; there won't be more than 256 original vehicles
|
||||
* in any case, and we just cleaned the pool. */
|
||||
assert(Engine::CanAllocateItem());
|
||||
const Engine *e = new Engine(eid.type, eid.internal_id);
|
||||
(void)e; // assert only
|
||||
[[maybe_unused]] const Engine *e = new Engine(eid.type, eid.internal_id);
|
||||
assert(e->index == index);
|
||||
index++;
|
||||
}
|
||||
@@ -837,7 +836,7 @@ void EnginesDailyLoop()
|
||||
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) {
|
||||
if (e->preview_company != INVALID_COMPANY) {
|
||||
if (!--e->preview_wait) {
|
||||
DeleteWindowById(WC_ENGINE_PREVIEW, i);
|
||||
CloseWindowById(WC_ENGINE_PREVIEW, i);
|
||||
e->preview_company = INVALID_COMPANY;
|
||||
}
|
||||
} else if (CountBits(e->preview_asked) < MAX_COMPANIES) {
|
||||
@@ -882,7 +881,7 @@ void ClearEnginesHiddenFlagOfCompany(CompanyID cid)
|
||||
* @param text Unused.
|
||||
* @return The cost of this operation or an error.
|
||||
*/
|
||||
CommandCost CmdSetVehicleVisibility(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdSetVehicleVisibility(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
Engine *e = Engine::GetIfValid(GB(p2, 0, 31));
|
||||
if (e == nullptr || _current_company >= MAX_COMPANIES) return CMD_ERROR;
|
||||
@@ -906,7 +905,7 @@ CommandCost CmdSetVehicleVisibility(TileIndex tile, DoCommandFlag flags, uint32
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
Engine *e = Engine::GetIfValid(p1);
|
||||
if (e == nullptr || !(e->flags & ENGINE_EXCLUSIVE_PREVIEW) || e->preview_company != _current_company) return CMD_ERROR;
|
||||
@@ -927,7 +926,7 @@ CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdEngineCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdEngineCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
if (_current_company != OWNER_DEITY) return CMD_ERROR;
|
||||
EngineID engine_id = (EngineID)p1;
|
||||
@@ -1015,7 +1014,7 @@ static void NewVehicleAvailable(Engine *e)
|
||||
if (e->type == VEH_AIRCRAFT) InvalidateWindowData(WC_BUILD_TOOLBAR, TRANSPORT_AIR);
|
||||
|
||||
/* Close pending preview windows */
|
||||
DeleteWindowById(WC_ENGINE_PREVIEW, index);
|
||||
CloseWindowById(WC_ENGINE_PREVIEW, index);
|
||||
}
|
||||
|
||||
/** Monthly update of the availability, reliability, and preview offers of the engines. */
|
||||
@@ -1061,7 +1060,7 @@ void EnginesMonthlyLoop()
|
||||
* @param name New name of an engine.
|
||||
* @return \c false if the name is being used already, else \c true.
|
||||
*/
|
||||
static bool IsUniqueEngineName(const char *name)
|
||||
static bool IsUniqueEngineName(const std::string &name)
|
||||
{
|
||||
for (const Engine *e : Engine::Iterate()) {
|
||||
if (!e->name.empty() && e->name == name) return false;
|
||||
@@ -1079,12 +1078,12 @@ static bool IsUniqueEngineName(const char *name)
|
||||
* @param text the new name or an empty string when resetting to the default
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdRenameEngine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
CommandCost CmdRenameEngine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
|
||||
{
|
||||
Engine *e = Engine::GetIfValid(p1);
|
||||
if (e == nullptr) return CMD_ERROR;
|
||||
|
||||
bool reset = StrEmpty(text);
|
||||
bool reset = text.empty();
|
||||
|
||||
if (!reset) {
|
||||
if (Utf8StringLength(text) >= MAX_LENGTH_ENGINE_NAME_CHARS) return CMD_ERROR;
|
||||
|
||||
@@ -128,7 +128,7 @@ struct EnginePreviewWindow : Window {
|
||||
DoCommandP(0, this->window_number, 0, CMD_WANT_ENGINE_PREVIEW);
|
||||
FALLTHROUGH;
|
||||
case WID_EP_NO:
|
||||
if (!_shift_pressed) delete this;
|
||||
if (!_shift_pressed) this->Close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,7 @@ struct EnginePreviewWindow : Window {
|
||||
if (!gui_scope) return;
|
||||
|
||||
EngineID engine = this->window_number;
|
||||
if (Engine::Get(engine)->preview_company != _local_company) delete this;
|
||||
if (Engine::Get(engine)->preview_company != _local_company) this->Close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ struct RailVehicleInfo {
|
||||
byte tractive_effort; ///< Tractive effort coefficient
|
||||
byte air_drag; ///< Coefficient of air drag
|
||||
byte user_def_data; ///< Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles
|
||||
int16 curve_speed_mod; ///< Modifier to maximum speed in curves (fixed-point binary with 8 fractional bits)
|
||||
};
|
||||
|
||||
/** Information about a ship vehicle. */
|
||||
|
||||
@@ -44,11 +44,15 @@ public:
|
||||
~ErrorMessageData();
|
||||
ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration = 0, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = nullptr, uint textref_stack_size = 0, const uint32 *textref_stack = nullptr);
|
||||
|
||||
/* Remove the copy assignment, as the default implementation will not do the right thing. */
|
||||
ErrorMessageData &operator=(ErrorMessageData &rhs) = delete;
|
||||
|
||||
/** Check whether error window shall display a company manager face */
|
||||
bool HasFace() const { return face != INVALID_COMPANY; }
|
||||
|
||||
void SetDParam(uint n, uint64 v);
|
||||
void SetDParamStr(uint n, const char *str);
|
||||
void SetDParamStr(uint n, const std::string &str);
|
||||
|
||||
void CopyOutDParams();
|
||||
};
|
||||
|
||||
@@ -170,6 +170,16 @@ void ErrorMessageData::SetDParamStr(uint n, const char *str)
|
||||
this->strings[n] = stredup(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a rawstring parameter.
|
||||
* @param n Parameter index
|
||||
* @param str Raw string
|
||||
*/
|
||||
void ErrorMessageData::SetDParamStr(uint n, const std::string &str)
|
||||
{
|
||||
this->SetDParamStr(n, str.c_str());
|
||||
}
|
||||
|
||||
/** Define a queue with errors. */
|
||||
typedef std::list<ErrorMessageData> ErrorList;
|
||||
/** The actual queue with errors. */
|
||||
@@ -256,7 +266,7 @@ public:
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
/* If company gets shut down, while displaying an error about it, remove the error message. */
|
||||
if (this->face != INVALID_COMPANY && !Company::IsValidID(this->face)) delete this;
|
||||
if (this->face != INVALID_COMPANY && !Company::IsValidID(this->face)) this->Close();
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
@@ -304,20 +314,21 @@ public:
|
||||
void OnMouseLoop() override
|
||||
{
|
||||
/* Disallow closing the window too easily, if timeout is disabled */
|
||||
if (_right_button_down && !this->display_timer.HasElapsed()) delete this;
|
||||
if (_right_button_down && !this->display_timer.HasElapsed()) this->Close();
|
||||
}
|
||||
|
||||
void OnRealtimeTick(uint delta_ms) override
|
||||
{
|
||||
if (this->display_timer.CountElapsed(delta_ms) == 0) return;
|
||||
|
||||
delete this;
|
||||
this->Close();
|
||||
}
|
||||
|
||||
~ErrmsgWindow()
|
||||
void Close() override
|
||||
{
|
||||
SetRedErrorSquare(INVALID_TILE);
|
||||
if (_window_system_initialized) ShowFirstError();
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
@@ -372,7 +383,7 @@ void UnshowCriticalError()
|
||||
if (_window_system_initialized && w != nullptr) {
|
||||
if (w->IsCritical()) _error_list.push_front(*w);
|
||||
_window_system_initialized = false;
|
||||
delete w;
|
||||
w->Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,10 +417,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel
|
||||
|
||||
if (textref_stack_size > 0) StopTextRefStackUsage();
|
||||
|
||||
switch (wl) {
|
||||
case WL_WARNING: IConsolePrint(CC_WARNING, buf); break;
|
||||
default: IConsoleError(buf); break;
|
||||
}
|
||||
IConsolePrint(wl == WL_WARNING ? CC_WARNING : CC_ERROR, buf);
|
||||
}
|
||||
|
||||
bool no_timeout = wl == WL_CRITICAL;
|
||||
@@ -421,18 +429,20 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel
|
||||
data.CopyOutDParams();
|
||||
|
||||
ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0);
|
||||
if (w != nullptr && w->IsCritical()) {
|
||||
/* A critical error is currently shown. */
|
||||
if (wl == WL_CRITICAL) {
|
||||
/* Push another critical error in the queue of errors,
|
||||
* but do not put other errors in the queue. */
|
||||
_error_list.push_back(data);
|
||||
if (w != nullptr) {
|
||||
if (w->IsCritical()) {
|
||||
/* A critical error is currently shown. */
|
||||
if (wl == WL_CRITICAL) {
|
||||
/* Push another critical error in the queue of errors,
|
||||
* but do not put other errors in the queue. */
|
||||
_error_list.push_back(data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Nothing or a non-critical error was shown. */
|
||||
delete w;
|
||||
new ErrmsgWindow(data);
|
||||
/* A non-critical error was shown. */
|
||||
w->Close();
|
||||
}
|
||||
new ErrmsgWindow(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -443,7 +453,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel
|
||||
bool HideActiveErrorMessage() {
|
||||
ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0);
|
||||
if (w == nullptr) return false;
|
||||
delete w;
|
||||
w->Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
301
src/fileio.cpp
301
src/fileio.cpp
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "fileio_func.h"
|
||||
#include "spriteloader/spriteloader.hpp"
|
||||
#include "debug.h"
|
||||
#include "fios.h"
|
||||
#include "string_func.h"
|
||||
@@ -29,192 +30,12 @@
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
/** Size of the #Fio data buffer. */
|
||||
#define FIO_BUFFER_SIZE 512
|
||||
|
||||
/** Structure for keeping several open files with just one data buffer. */
|
||||
struct Fio {
|
||||
byte *buffer, *buffer_end; ///< position pointer in local buffer and last valid byte of buffer
|
||||
byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file
|
||||
size_t pos; ///< current (system) position in file
|
||||
FILE *cur_fh; ///< current file handle
|
||||
std::string filename; ///< current filename
|
||||
std::array<FILE *, MAX_FILE_SLOTS> handles; ///< array of file handles we can have open
|
||||
std::array<std::string, MAX_FILE_SLOTS> filenames; ///< array of filenames we (should) have open
|
||||
std::array<std::string, MAX_FILE_SLOTS> shortnames;///< array of short names for spriteloader's use
|
||||
};
|
||||
|
||||
static Fio _fio; ///< #Fio instance.
|
||||
|
||||
/** Whether the working directory should be scanned. */
|
||||
static bool _do_scan_working_directory = true;
|
||||
|
||||
extern std::string _config_file;
|
||||
extern std::string _highscore_file;
|
||||
|
||||
/**
|
||||
* Get position in the current file.
|
||||
* @return Position in the file.
|
||||
*/
|
||||
size_t FioGetPos()
|
||||
{
|
||||
return _fio.pos + (_fio.buffer - _fio.buffer_end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filename associated with a slot.
|
||||
* @param slot Index of queried file.
|
||||
* @return Name of the file.
|
||||
*/
|
||||
const char *FioGetFilename(uint8 slot)
|
||||
{
|
||||
return _fio.shortnames[slot].c_str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek in the current file.
|
||||
* @param pos New position.
|
||||
* @param mode Type of seek (\c SEEK_CUR means \a pos is relative to current position, \c SEEK_SET means \a pos is absolute).
|
||||
*/
|
||||
void FioSeekTo(size_t pos, int mode)
|
||||
{
|
||||
if (mode == SEEK_CUR) pos += FioGetPos();
|
||||
_fio.buffer = _fio.buffer_end = _fio.buffer_start + FIO_BUFFER_SIZE;
|
||||
_fio.pos = pos;
|
||||
if (fseek(_fio.cur_fh, _fio.pos, SEEK_SET) < 0) {
|
||||
DEBUG(misc, 0, "Seeking in %s failed", _fio.filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to a different file and seek to a position.
|
||||
* @param slot Slot number of the new file.
|
||||
* @param pos New absolute position in the new file.
|
||||
*/
|
||||
void FioSeekToFile(uint8 slot, size_t pos)
|
||||
{
|
||||
FILE *f = _fio.handles[slot];
|
||||
assert(f != nullptr);
|
||||
_fio.cur_fh = f;
|
||||
_fio.filename = _fio.filenames[slot];
|
||||
FioSeekTo(pos, SEEK_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a byte from the file.
|
||||
* @return Read byte.
|
||||
*/
|
||||
byte FioReadByte()
|
||||
{
|
||||
if (_fio.buffer == _fio.buffer_end) {
|
||||
_fio.buffer = _fio.buffer_start;
|
||||
size_t size = fread(_fio.buffer, 1, FIO_BUFFER_SIZE, _fio.cur_fh);
|
||||
_fio.pos += size;
|
||||
_fio.buffer_end = _fio.buffer_start + size;
|
||||
|
||||
if (size == 0) return 0;
|
||||
}
|
||||
return *_fio.buffer++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip \a n bytes ahead in the file.
|
||||
* @param n Number of bytes to skip reading.
|
||||
*/
|
||||
void FioSkipBytes(int n)
|
||||
{
|
||||
for (;;) {
|
||||
int m = std::min<int>(_fio.buffer_end - _fio.buffer, n);
|
||||
_fio.buffer += m;
|
||||
n -= m;
|
||||
if (n == 0) break;
|
||||
FioReadByte();
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a word (16 bits) from the file (in low endian format).
|
||||
* @return Read word.
|
||||
*/
|
||||
uint16 FioReadWord()
|
||||
{
|
||||
byte b = FioReadByte();
|
||||
return (FioReadByte() << 8) | b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a double word (32 bits) from the file (in low endian format).
|
||||
* @return Read word.
|
||||
*/
|
||||
uint32 FioReadDword()
|
||||
{
|
||||
uint b = FioReadWord();
|
||||
return (FioReadWord() << 16) | b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a block.
|
||||
* @param ptr Destination buffer.
|
||||
* @param size Number of bytes to read.
|
||||
*/
|
||||
void FioReadBlock(void *ptr, size_t size)
|
||||
{
|
||||
FioSeekTo(FioGetPos(), SEEK_SET);
|
||||
_fio.pos += fread(ptr, 1, size, _fio.cur_fh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the file at the given slot number.
|
||||
* @param slot File index to close.
|
||||
*/
|
||||
static inline void FioCloseFile(int slot)
|
||||
{
|
||||
if (_fio.handles[slot] != nullptr) {
|
||||
fclose(_fio.handles[slot]);
|
||||
|
||||
_fio.shortnames[slot].clear();
|
||||
|
||||
_fio.handles[slot] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/** Close all slotted open files. */
|
||||
void FioCloseAll()
|
||||
{
|
||||
for (int i = 0; i != lengthof(_fio.handles); i++) {
|
||||
FioCloseFile(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a slotted file.
|
||||
* @param slot Index to assign.
|
||||
* @param filename Name of the file at the disk.
|
||||
* @param subdir The sub directory to search this file in.
|
||||
*/
|
||||
void FioOpenFile(int slot, const std::string &filename, Subdirectory subdir)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = FioFOpenFile(filename, "rb", subdir);
|
||||
if (f == nullptr) usererror("Cannot open file '%s'", filename.c_str());
|
||||
long pos = ftell(f);
|
||||
if (pos < 0) usererror("Cannot read file '%s'", filename.c_str());
|
||||
|
||||
FioCloseFile(slot); // if file was opened before, close it
|
||||
_fio.handles[slot] = f;
|
||||
_fio.filenames[slot] = filename;
|
||||
|
||||
/* Store the filename without path and extension */
|
||||
auto t = filename.rfind(PATHSEPCHAR);
|
||||
std::string sn = filename.substr(t != std::string::npos ? t + 1 : 0);
|
||||
_fio.shortnames[slot] = sn.substr(0, sn.rfind('.'));
|
||||
strtolower(_fio.shortnames[slot]);
|
||||
|
||||
FioSeekToFile(slot, (size_t)pos);
|
||||
}
|
||||
|
||||
static const char * const _subdirs[] = {
|
||||
"",
|
||||
"save" PATHSEP,
|
||||
@@ -241,6 +62,7 @@ static_assert(lengthof(_subdirs) == NUM_SUBDIRS);
|
||||
* current operating system.
|
||||
*/
|
||||
std::array<std::string, NUM_SEARCHPATHS> _searchpaths;
|
||||
std::vector<Searchpath> _valid_searchpaths;
|
||||
std::array<TarList, NUM_SUBDIRS> _tar_list;
|
||||
TarFileList _tar_filelist[NUM_SUBDIRS];
|
||||
|
||||
@@ -252,11 +74,31 @@ static TarLinkList _tar_linklist[NUM_SUBDIRS]; ///< List of directory links
|
||||
* @param sp the search path to check
|
||||
* @return true if the search path is valid
|
||||
*/
|
||||
bool IsValidSearchPath(Searchpath sp)
|
||||
static bool IsValidSearchPath(Searchpath sp)
|
||||
{
|
||||
return sp < _searchpaths.size() && !_searchpaths[sp].empty();
|
||||
}
|
||||
|
||||
static void FillValidSearchPaths(bool only_local_path)
|
||||
{
|
||||
_valid_searchpaths.clear();
|
||||
for (Searchpath sp = SP_FIRST_DIR; sp < NUM_SEARCHPATHS; sp++) {
|
||||
if (only_local_path) {
|
||||
switch (sp) {
|
||||
case SP_WORKING_DIR: // Can be influence by "-c" option.
|
||||
case SP_BINARY_DIR: // Most likely contains all the language files.
|
||||
case SP_AUTODOWNLOAD_DIR: // Otherwise we cannot download in-game content.
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsValidSearchPath(sp)) _valid_searchpaths.emplace_back(sp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given file exists
|
||||
* @param filename the file to try for existence.
|
||||
@@ -298,10 +140,9 @@ void FioFCloseFile(FILE *f)
|
||||
*/
|
||||
std::string FioFindFullPath(Subdirectory subdir, const char *filename)
|
||||
{
|
||||
Searchpath sp;
|
||||
assert(subdir < NUM_SUBDIRS);
|
||||
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
for (Searchpath sp : _valid_searchpaths) {
|
||||
std::string buf = FioGetDirectory(sp, subdir);
|
||||
buf += filename;
|
||||
if (FileExists(buf)) return buf;
|
||||
@@ -326,10 +167,8 @@ std::string FioGetDirectory(Searchpath sp, Subdirectory subdir)
|
||||
|
||||
std::string FioFindDirectory(Subdirectory subdir)
|
||||
{
|
||||
Searchpath sp;
|
||||
|
||||
/* Find and return the first valid directory */
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
for (Searchpath sp : _valid_searchpaths) {
|
||||
std::string ret = FioGetDirectory(sp, subdir);
|
||||
if (FileExists(ret)) return ret;
|
||||
}
|
||||
@@ -406,11 +245,10 @@ FILE *FioFOpenFileTar(const TarFileListEntry &entry, size_t *filesize)
|
||||
FILE *FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize)
|
||||
{
|
||||
FILE *f = nullptr;
|
||||
Searchpath sp;
|
||||
|
||||
assert(subdir < NUM_SUBDIRS || subdir == NO_DIRECTORY);
|
||||
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
for (Searchpath sp : _valid_searchpaths) {
|
||||
f = FioFOpenFileSp(filename, mode, sp, subdir, filesize);
|
||||
if (f != nullptr || subdir == NO_DIRECTORY) break;
|
||||
}
|
||||
@@ -580,7 +418,7 @@ uint TarScanner::DoScan(Subdirectory sd)
|
||||
|
||||
/* static */ uint TarScanner::DoScan(TarScanner::Mode mode)
|
||||
{
|
||||
DEBUG(misc, 1, "Scanning for tars");
|
||||
Debug(misc, 1, "Scanning for tars");
|
||||
TarScanner fs;
|
||||
uint num = 0;
|
||||
if (mode & TarScanner::BASESET) {
|
||||
@@ -601,7 +439,7 @@ uint TarScanner::DoScan(Subdirectory sd)
|
||||
num += fs.DoScan(SCENARIO_DIR);
|
||||
num += fs.DoScan(HEIGHTMAP_DIR);
|
||||
}
|
||||
DEBUG(misc, 1, "Scan complete, found %d files", num);
|
||||
Debug(misc, 1, "Scan complete, found {} files", num);
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -680,7 +518,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
/* If we have only zeros in the block, it can be an end-of-file indicator */
|
||||
if (memcmp(&th, &empty[0], 512) == 0) continue;
|
||||
|
||||
DEBUG(misc, 0, "The file '%s' isn't a valid tar-file", filename.c_str());
|
||||
Debug(misc, 0, "The file '{}' isn't a valid tar-file", filename);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
@@ -703,9 +541,6 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
switch (th.typeflag) {
|
||||
case '\0':
|
||||
case '0': { // regular file
|
||||
/* Ignore empty files */
|
||||
if (skip == 0) break;
|
||||
|
||||
if (strlen(name) == 0) break;
|
||||
|
||||
/* Store this entry in the list */
|
||||
@@ -717,7 +552,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
/* Convert to lowercase and our PATHSEPCHAR */
|
||||
SimplifyFileName(name);
|
||||
|
||||
DEBUG(misc, 6, "Found file in tar: %s (" PRINTF_SIZE " bytes, " PRINTF_SIZE " offset)", name, skip, pos);
|
||||
Debug(misc, 6, "Found file in tar: {} ({} bytes, {} offset)", name, skip, pos);
|
||||
if (_tar_filelist[this->subdir].insert(TarFileList::value_type(name, entry)).second) num++;
|
||||
|
||||
break;
|
||||
@@ -736,7 +571,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
|
||||
/* Only allow relative links */
|
||||
if (link[0] == PATHSEPCHAR) {
|
||||
DEBUG(misc, 1, "Ignoring absolute link in tar: %s -> %s", name, link);
|
||||
Debug(misc, 1, "Ignoring absolute link in tar: {} -> {}", name, link);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -762,7 +597,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
} else if (strcmp(pos, "..") == 0) {
|
||||
/* level up */
|
||||
if (dest[0] == '\0') {
|
||||
DEBUG(misc, 1, "Ignoring link pointing outside of data directory: %s -> %s", name, link);
|
||||
Debug(misc, 1, "Ignoring link pointing outside of data directory: {} -> {}", name, link);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -778,7 +613,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
}
|
||||
|
||||
if (destpos >= lastof(dest)) {
|
||||
DEBUG(misc, 0, "The length of a link in tar-file '%s' is too large (malformed?)", filename.c_str());
|
||||
Debug(misc, 0, "The length of a link in tar-file '{}' is too large (malformed?)", filename);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
@@ -787,7 +622,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
}
|
||||
|
||||
/* Store links in temporary list */
|
||||
DEBUG(misc, 6, "Found link in tar: %s -> %s", name, dest);
|
||||
Debug(misc, 6, "Found link in tar: {} -> {}", name, dest);
|
||||
links.insert(TarLinkList::value_type(name, dest));
|
||||
|
||||
break;
|
||||
@@ -798,7 +633,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
SimplifyFileName(name);
|
||||
|
||||
/* Store the first directory name we detect */
|
||||
DEBUG(misc, 6, "Found dir in tar: %s", name);
|
||||
Debug(misc, 6, "Found dir in tar: {}", name);
|
||||
if (_tar_list[this->subdir][filename].empty()) _tar_list[this->subdir][filename] = name;
|
||||
break;
|
||||
|
||||
@@ -810,14 +645,14 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
|
||||
/* Skip to the next block.. */
|
||||
skip = Align(skip, 512);
|
||||
if (fseek(f, skip, SEEK_CUR) < 0) {
|
||||
DEBUG(misc, 0, "The file '%s' can't be read as a valid tar-file", filename.c_str());
|
||||
Debug(misc, 0, "The file '{}' can't be read as a valid tar-file", filename);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
pos += skip;
|
||||
}
|
||||
|
||||
DEBUG(misc, 1, "Found tar '%s' with " PRINTF_SIZE " new files", filename.c_str(), num);
|
||||
Debug(misc, 1, "Found tar '{}' with {} new files", filename, num);
|
||||
fclose(f);
|
||||
|
||||
/* Resolve file links and store directory links.
|
||||
@@ -855,7 +690,7 @@ bool ExtractTar(const std::string &tar_filename, Subdirectory subdir)
|
||||
|
||||
/* The file doesn't have a sub directory! */
|
||||
if (dirname.empty()) {
|
||||
DEBUG(misc, 1, "Extracting %s failed; archive rejected, the contents must be in a sub directory", tar_filename.c_str());
|
||||
Debug(misc, 1, "Extracting {} failed; archive rejected, the contents must be in a sub directory", tar_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -865,7 +700,7 @@ bool ExtractTar(const std::string &tar_filename, Subdirectory subdir)
|
||||
if (p == std::string::npos) return false;
|
||||
|
||||
filename.replace(p + 1, std::string::npos, dirname);
|
||||
DEBUG(misc, 8, "Extracting %s to directory %s", tar_filename.c_str(), filename.c_str());
|
||||
Debug(misc, 8, "Extracting {} to directory {}", tar_filename, filename);
|
||||
FioCreateDirectory(filename);
|
||||
|
||||
for (TarFileList::iterator it2 = _tar_filelist[subdir].begin(); it2 != _tar_filelist[subdir].end(); it2++) {
|
||||
@@ -873,20 +708,20 @@ bool ExtractTar(const std::string &tar_filename, Subdirectory subdir)
|
||||
|
||||
filename.replace(p + 1, std::string::npos, it2->first);
|
||||
|
||||
DEBUG(misc, 9, " extracting %s", filename.c_str());
|
||||
Debug(misc, 9, " extracting {}", filename);
|
||||
|
||||
/* First open the file in the .tar. */
|
||||
size_t to_copy = 0;
|
||||
std::unique_ptr<FILE, FileDeleter> in(FioFOpenFileTar(it2->second, &to_copy));
|
||||
if (!in) {
|
||||
DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename.c_str(), tar_filename.c_str());
|
||||
Debug(misc, 6, "Extracting {} failed; could not open {}", filename, tar_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Now open the 'output' file. */
|
||||
std::unique_ptr<FILE, FileDeleter> out(fopen(filename.c_str(), "wb"));
|
||||
if (!out) {
|
||||
DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename.c_str(), filename.c_str());
|
||||
Debug(misc, 6, "Extracting {} failed; could not open {}", filename, filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -899,12 +734,12 @@ bool ExtractTar(const std::string &tar_filename, Subdirectory subdir)
|
||||
}
|
||||
|
||||
if (to_copy != 0) {
|
||||
DEBUG(misc, 6, "Extracting %s failed; still %i bytes to copy", filename.c_str(), (int)to_copy);
|
||||
Debug(misc, 6, "Extracting {} failed; still {} bytes to copy", filename, to_copy);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(misc, 9, " extraction successful");
|
||||
Debug(misc, 9, " extraction successful");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -940,7 +775,7 @@ static bool ChangeWorkingDirectoryToExecutable(const char *exe)
|
||||
if (s != nullptr) {
|
||||
*s = '\0';
|
||||
if (chdir(tmp) != 0) {
|
||||
DEBUG(misc, 0, "Directory with the binary does not exist?");
|
||||
Debug(misc, 0, "Directory with the binary does not exist?");
|
||||
} else {
|
||||
success = true;
|
||||
}
|
||||
@@ -987,7 +822,7 @@ static std::string GetHomeDir()
|
||||
find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
return std::string(path.Path());
|
||||
#else
|
||||
const char *home_env = getenv("HOME"); // Stack var, shouldn't be freed
|
||||
const char *home_env = std::getenv("HOME"); // Stack var, shouldn't be freed
|
||||
if (home_env != nullptr) return std::string(home_env);
|
||||
|
||||
const struct passwd *pw = getpwuid(getuid());
|
||||
@@ -1005,7 +840,7 @@ void DetermineBasePaths(const char *exe)
|
||||
std::string tmp;
|
||||
const std::string homedir = GetHomeDir();
|
||||
#ifdef USE_XDG
|
||||
const char *xdg_data_home = getenv("XDG_DATA_HOME");
|
||||
const char *xdg_data_home = std::getenv("XDG_DATA_HOME");
|
||||
if (xdg_data_home != nullptr) {
|
||||
tmp = xdg_data_home;
|
||||
tmp += PATHSEP;
|
||||
@@ -1099,7 +934,7 @@ void DetermineBasePaths(const char *exe)
|
||||
if (cwd[0] != '\0') {
|
||||
/* Go back to the current working directory. */
|
||||
if (chdir(cwd) != 0) {
|
||||
DEBUG(misc, 0, "Failed to return to working directory!");
|
||||
Debug(misc, 0, "Failed to return to working directory!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1126,15 +961,17 @@ std::string _personal_dir;
|
||||
* fill all other paths (save dir, autosave dir etc) and
|
||||
* make the save and scenario directories.
|
||||
* @param exe the path from the current path to the executable
|
||||
* @param only_local_path Whether we shouldn't fill searchpaths with global folders.
|
||||
*/
|
||||
void DeterminePaths(const char *exe)
|
||||
void DeterminePaths(const char *exe, bool only_local_path)
|
||||
{
|
||||
DetermineBasePaths(exe);
|
||||
FillValidSearchPaths(only_local_path);
|
||||
|
||||
#ifdef USE_XDG
|
||||
std::string config_home;
|
||||
const std::string homedir = GetHomeDir();
|
||||
const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
|
||||
const char *xdg_config_home = std::getenv("XDG_CONFIG_HOME");
|
||||
if (xdg_config_home != nullptr) {
|
||||
config_home = xdg_config_home;
|
||||
config_home += PATHSEP;
|
||||
@@ -1148,10 +985,9 @@ void DeterminePaths(const char *exe)
|
||||
AppendPathSeparator(config_home);
|
||||
#endif
|
||||
|
||||
Searchpath sp;
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
for (Searchpath sp : _valid_searchpaths) {
|
||||
if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue;
|
||||
DEBUG(misc, 4, "%s added as search path", _searchpaths[sp].c_str());
|
||||
Debug(misc, 4, "{} added as search path", _searchpaths[sp]);
|
||||
}
|
||||
|
||||
std::string config_dir;
|
||||
@@ -1184,19 +1020,30 @@ void DeterminePaths(const char *exe)
|
||||
_config_file = config_dir + "openttd.cfg";
|
||||
}
|
||||
|
||||
DEBUG(misc, 3, "%s found as config directory", config_dir.c_str());
|
||||
Debug(misc, 3, "{} found as config directory", config_dir);
|
||||
|
||||
_highscore_file = config_dir + "hs.dat";
|
||||
extern std::string _hotkeys_file;
|
||||
_hotkeys_file = config_dir + "hotkeys.cfg";
|
||||
extern std::string _windows_file;
|
||||
_windows_file = config_dir + "windows.cfg";
|
||||
extern std::string _private_file;
|
||||
_private_file = config_dir + "private.cfg";
|
||||
extern std::string _secrets_file;
|
||||
_secrets_file = config_dir + "secrets.cfg";
|
||||
|
||||
#ifdef USE_XDG
|
||||
if (config_dir == config_home) {
|
||||
/* We are using the XDG configuration home for the config file,
|
||||
* then store the rest in the XDG data home folder. */
|
||||
_personal_dir = _searchpaths[SP_PERSONAL_DIR_XDG];
|
||||
if (only_local_path) {
|
||||
/* In case of XDG and we only want local paths and we detected that
|
||||
* the user either manually indicated the XDG path or didn't use
|
||||
* "-c" option, we change the working-dir to the XDG personal-dir,
|
||||
* as this is most likely what the user is expecting. */
|
||||
_searchpaths[SP_WORKING_DIR] = _searchpaths[SP_PERSONAL_DIR_XDG];
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@@ -1209,7 +1056,7 @@ void DeterminePaths(const char *exe)
|
||||
FioCreateDirectory(_personal_dir);
|
||||
#endif
|
||||
|
||||
DEBUG(misc, 3, "%s found as personal directory", _personal_dir.c_str());
|
||||
Debug(misc, 3, "{} found as personal directory", _personal_dir);
|
||||
|
||||
static const Subdirectory default_subdirs[] = {
|
||||
SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR, SCREENSHOT_DIR
|
||||
@@ -1221,7 +1068,9 @@ void DeterminePaths(const char *exe)
|
||||
|
||||
/* If we have network we make a directory for the autodownloading of content */
|
||||
_searchpaths[SP_AUTODOWNLOAD_DIR] = _personal_dir + "content_download" PATHSEP;
|
||||
Debug(misc, 4, "{} added as search path", _searchpaths[SP_AUTODOWNLOAD_DIR]);
|
||||
FioCreateDirectory(_searchpaths[SP_AUTODOWNLOAD_DIR]);
|
||||
FillValidSearchPaths(only_local_path);
|
||||
|
||||
/* Create the directory for each of the types of content */
|
||||
const Subdirectory dirs[] = { SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR };
|
||||
@@ -1345,12 +1194,12 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s
|
||||
* @param extension the extension of files to search for.
|
||||
* @param tar the tar to search in.
|
||||
*/
|
||||
static uint ScanTar(FileScanner *fs, const char *extension, TarFileList::iterator tar)
|
||||
static uint ScanTar(FileScanner *fs, const char *extension, const TarFileList::value_type &tar)
|
||||
{
|
||||
uint num = 0;
|
||||
const auto &filename = (*tar).first;
|
||||
const auto &filename = tar.first;
|
||||
|
||||
if (MatchesExtension(extension, filename.c_str()) && fs->AddFile(filename, 0, (*tar).second.tar_filename)) num++;
|
||||
if (MatchesExtension(extension, filename.c_str()) && fs->AddFile(filename, 0, tar.second.tar_filename)) num++;
|
||||
|
||||
return num;
|
||||
}
|
||||
@@ -1368,11 +1217,9 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r
|
||||
{
|
||||
this->subdir = sd;
|
||||
|
||||
Searchpath sp;
|
||||
TarFileList::iterator tar;
|
||||
uint num = 0;
|
||||
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
for (Searchpath sp : _valid_searchpaths) {
|
||||
/* Don't search in the working directory */
|
||||
if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue;
|
||||
|
||||
@@ -1381,7 +1228,7 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r
|
||||
}
|
||||
|
||||
if (tars && sd != NO_DIRECTORY) {
|
||||
FOR_ALL_TARS(tar, sd) {
|
||||
for (const auto &tar : _tar_filelist[sd]) {
|
||||
num += ScanTar(this, extension, tar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,28 +13,7 @@
|
||||
#include "core/enum_type.hpp"
|
||||
#include "fileio_type.h"
|
||||
#include <string>
|
||||
|
||||
void FioSeekTo(size_t pos, int mode);
|
||||
void FioSeekToFile(uint8 slot, size_t pos);
|
||||
size_t FioGetPos();
|
||||
const char *FioGetFilename(uint8 slot);
|
||||
byte FioReadByte();
|
||||
uint16 FioReadWord();
|
||||
uint32 FioReadDword();
|
||||
void FioCloseAll();
|
||||
void FioOpenFile(int slot, const std::string &filename, Subdirectory subdir);
|
||||
void FioReadBlock(void *ptr, size_t size);
|
||||
void FioSkipBytes(int n);
|
||||
|
||||
/**
|
||||
* Checks whether the given search path is a valid search path
|
||||
* @param sp the search path to check
|
||||
* @return true if the search path is valid
|
||||
*/
|
||||
bool IsValidSearchPath(Searchpath sp);
|
||||
|
||||
/** Iterator for all the search paths */
|
||||
#define FOR_ALL_SEARCHPATHS(sp) for (sp = SP_FIRST_DIR; sp < NUM_SEARCHPATHS; sp++) if (IsValidSearchPath(sp))
|
||||
#include <vector>
|
||||
|
||||
void FioFCloseFile(FILE *f);
|
||||
FILE *FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize = nullptr);
|
||||
@@ -48,12 +27,13 @@ const char *FiosGetScreenshotDir();
|
||||
|
||||
void SanitizeFilename(char *filename);
|
||||
void AppendPathSeparator(std::string &buf);
|
||||
void DeterminePaths(const char *exe);
|
||||
void DeterminePaths(const char *exe, bool only_local_path);
|
||||
std::unique_ptr<char[]> ReadFileToMem(const std::string &filename, size_t &lenp, size_t maxsize);
|
||||
bool FileExists(const std::string &filename);
|
||||
bool ExtractTar(const std::string &tar_filename, Subdirectory subdir);
|
||||
|
||||
extern std::string _personal_dir; ///< custom directory for personal settings, saves, newgrf, etc.
|
||||
extern std::vector<Searchpath> _valid_searchpaths;
|
||||
|
||||
/** Helper for scanning for files with a given name */
|
||||
class FileScanner {
|
||||
|
||||
68
src/fios.cpp
68
src/fios.cpp
@@ -22,6 +22,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <charconv>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h>
|
||||
@@ -342,7 +343,7 @@ bool FiosFileScanner::AddFile(const std::string &filename, size_t basepath_lengt
|
||||
t = filename.c_str() + (ps == std::string::npos ? 0 : ps + 1);
|
||||
}
|
||||
strecpy(fios->title, t, lastof(fios->title));
|
||||
str_validate(fios->title, lastof(fios->title));
|
||||
StrMakeValidInPlace(fios->title, lastof(fios->title));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -392,9 +393,9 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c
|
||||
fios->mtime = 0;
|
||||
strecpy(fios->name, d_name, lastof(fios->name));
|
||||
std::string dirname = std::string(d_name) + PATHSEP;
|
||||
SetDParamStr(0, dirname.c_str());
|
||||
SetDParamStr(0, dirname);
|
||||
GetString(fios->title, STR_SAVELOAD_DIRECTORY, lastof(fios->title));
|
||||
str_validate(fios->title, lastof(fios->title));
|
||||
StrMakeValidInPlace(fios->title, lastof(fios->title));
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
@@ -446,7 +447,7 @@ static void GetFileTitle(const std::string &file, char *title, const char *last,
|
||||
size_t read = fread(title, 1, last - title, f);
|
||||
assert(title + read <= last);
|
||||
title[read] = '\0';
|
||||
str_validate(title, last);
|
||||
StrMakeValidInPlace(title, last);
|
||||
FioFCloseFile(f);
|
||||
}
|
||||
|
||||
@@ -582,8 +583,7 @@ static FiosType FiosGetHeightmapListCallback(SaveLoadOperation fop, const std::s
|
||||
* collections of NewGRFs or 32 bpp graphics replacement PNGs.
|
||||
*/
|
||||
bool match = false;
|
||||
Searchpath sp;
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
for (Searchpath sp : _valid_searchpaths) {
|
||||
std::string buf = FioGetDirectory(sp, HEIGHTMAP_DIR);
|
||||
|
||||
if (buf.compare(0, buf.size(), it->second.tar_filename, 0, buf.size()) == 0) {
|
||||
@@ -746,3 +746,59 @@ void ScanScenarios()
|
||||
{
|
||||
_scanner.Scan(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs FiosNumberedSaveName. Initial number is the most recent save, or -1 if not found.
|
||||
* @param prefix The prefix to use to generate a filename.
|
||||
*/
|
||||
FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(prefix), number(-1)
|
||||
{
|
||||
static std::optional<std::string> _autosave_path;
|
||||
if (!_autosave_path) _autosave_path = FioFindDirectory(AUTOSAVE_DIR);
|
||||
|
||||
static std::string _prefix; ///< Static as the lambda needs access to it.
|
||||
|
||||
/* Callback for FiosFileScanner. */
|
||||
static fios_getlist_callback_proc *proc = [](SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last) {
|
||||
if (strcasecmp(ext, ".sav") == 0 && StrStartsWith(file, _prefix)) return FIOS_TYPE_FILE;
|
||||
return FIOS_TYPE_INVALID;
|
||||
};
|
||||
|
||||
/* Prefix to check in the callback. */
|
||||
_prefix = *_autosave_path + this->prefix;
|
||||
|
||||
/* Get the save list. */
|
||||
FileList list;
|
||||
FiosFileScanner scanner(SLO_SAVE, proc, list);
|
||||
scanner.Scan(".sav", _autosave_path->c_str(), false);
|
||||
|
||||
/* Find the number for the most recent save, if any. */
|
||||
if (list.begin() != list.end()) {
|
||||
SortingBits order = _savegame_sort_order;
|
||||
_savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
|
||||
std::sort(list.begin(), list.end());
|
||||
_savegame_sort_order = order;
|
||||
|
||||
std::string_view name = list.begin()->title;
|
||||
std::from_chars(name.data() + this->prefix.size(), name.data() + name.size(), this->number);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a savegame name and number according to _settings_client.gui.max_num_autosaves.
|
||||
* @return A filename in format "<prefix><number>.sav".
|
||||
*/
|
||||
std::string FiosNumberedSaveName::Filename()
|
||||
{
|
||||
if (++this->number >= _settings_client.gui.max_num_autosaves) this->number = 0;
|
||||
return fmt::format("{}{}.sav", this->prefix, this->number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an extension for a savegame name.
|
||||
* @return An extension in format "-<prefix>.sav".
|
||||
*/
|
||||
std::string FiosNumberedSaveName::Extension()
|
||||
{
|
||||
return fmt::format("-{}.sav", this->prefix);
|
||||
}
|
||||
|
||||
28
src/fios.h
28
src/fios.h
@@ -83,22 +83,6 @@ struct LoadCheckData {
|
||||
|
||||
extern LoadCheckData _load_check_data;
|
||||
|
||||
|
||||
enum FileSlots {
|
||||
/**
|
||||
* Slot used for the GRF scanning and such.
|
||||
* This slot is used for all temporary accesses to files when scanning/testing files,
|
||||
* and thus cannot be used for files, which are continuously accessed during a game.
|
||||
*/
|
||||
CONFIG_SLOT = 0,
|
||||
/** Slot for the sound. */
|
||||
SOUND_SLOT = 1,
|
||||
/** First slot usable for (New)GRFs used during the game. */
|
||||
FIRST_GRF_SLOT = 2,
|
||||
/** Maximum number of slots. */
|
||||
MAX_FILE_SLOTS = 128,
|
||||
};
|
||||
|
||||
/** Deals with finding savegames */
|
||||
struct FiosItem {
|
||||
FiosType type;
|
||||
@@ -141,4 +125,16 @@ std::string FiosMakeSavegameName(const char *name);
|
||||
|
||||
FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last);
|
||||
|
||||
/**
|
||||
* A savegame name automatically numbered.
|
||||
*/
|
||||
struct FiosNumberedSaveName {
|
||||
FiosNumberedSaveName(const std::string &prefix);
|
||||
std::string Filename();
|
||||
std::string Extension();
|
||||
private:
|
||||
std::string prefix;
|
||||
int number;
|
||||
};
|
||||
|
||||
#endif /* FIOS_H */
|
||||
|
||||
@@ -56,7 +56,7 @@ void LoadCheckData::Clear()
|
||||
|
||||
this->map_size_x = this->map_size_y = 256; // Default for old savegames which do not store mapsize.
|
||||
this->current_date = 0;
|
||||
memset(&this->settings, 0, sizeof(this->settings));
|
||||
this->settings = {};
|
||||
|
||||
for (auto &pair : this->companies) {
|
||||
delete pair.second;
|
||||
@@ -405,12 +405,13 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~SaveLoadWindow()
|
||||
void Close() override
|
||||
{
|
||||
/* pause is only used in single-player, non-editor mode, non menu mode */
|
||||
if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
|
||||
DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
|
||||
}
|
||||
this->Window::Close();
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
@@ -544,7 +545,7 @@ public:
|
||||
const CompanyProperties &c = *pair.second;
|
||||
if (!c.name.empty()) {
|
||||
SetDParam(1, STR_JUST_RAW_STRING);
|
||||
SetDParamStr(2, c.name.c_str());
|
||||
SetDParamStr(2, c.name);
|
||||
} else {
|
||||
SetDParam(1, c.name_1);
|
||||
SetDParam(2, c.name_2);
|
||||
@@ -624,12 +625,12 @@ public:
|
||||
_file_to_saveload.SetTitle(this->selected->title);
|
||||
|
||||
if (this->abstract_filetype == FT_HEIGHTMAP) {
|
||||
delete this;
|
||||
this->Close();
|
||||
ShowHeightmapLoad();
|
||||
} else if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
|
||||
_switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
|
||||
ClearErrorMessages();
|
||||
delete this;
|
||||
this->Close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -695,7 +696,7 @@ public:
|
||||
_file_to_saveload.SetName(name);
|
||||
_file_to_saveload.SetTitle(file->title);
|
||||
|
||||
delete this;
|
||||
this->Close();
|
||||
ShowHeightmapLoad();
|
||||
}
|
||||
}
|
||||
@@ -767,7 +768,7 @@ public:
|
||||
EventState OnKeyPress(WChar key, uint16 keycode) override
|
||||
{
|
||||
if (keycode == WKC_ESC) {
|
||||
delete this;
|
||||
this->Close();
|
||||
return ES_HANDLED;
|
||||
}
|
||||
|
||||
@@ -885,7 +886,7 @@ public:
|
||||
this->fios_items_shown[i] = this->string_filter.GetState();
|
||||
if (this->fios_items_shown[i]) items_shown_count++;
|
||||
|
||||
if (&(this->fios_items[i]) == this->selected && this->fios_items_shown[i] == false) {
|
||||
if (&(this->fios_items[i]) == this->selected && !this->fios_items_shown[i]) {
|
||||
/* The selected element has been filtered out */
|
||||
this->selected = nullptr;
|
||||
this->OnInvalidateData(SLIWD_SELECTION_CHANGES);
|
||||
@@ -937,7 +938,7 @@ static WindowDesc _save_dialog_desc(
|
||||
*/
|
||||
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop)
|
||||
{
|
||||
DeleteWindowById(WC_SAVELOAD, 0);
|
||||
CloseWindowById(WC_SAVELOAD, 0);
|
||||
|
||||
WindowDesc *sld;
|
||||
if (fop == SLO_SAVE) {
|
||||
|
||||
@@ -216,7 +216,8 @@ TrueTypeFontCache::TrueTypeFontCache(FontSize fs, int pixels) : FontCache(fs), r
|
||||
*/
|
||||
TrueTypeFontCache::~TrueTypeFontCache()
|
||||
{
|
||||
this->ClearFontCache();
|
||||
/* Virtual functions get called statically in destructors, so make it explicit to remove any confusion. */
|
||||
this->TrueTypeFontCache::ClearFontCache();
|
||||
|
||||
for (auto &iter : this->font_tables) {
|
||||
free(iter.second.second);
|
||||
@@ -258,16 +259,16 @@ TrueTypeFontCache::GlyphEntry *TrueTypeFontCache::GetGlyphPtr(GlyphID key)
|
||||
void TrueTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate)
|
||||
{
|
||||
if (this->glyph_to_sprite == nullptr) {
|
||||
DEBUG(freetype, 3, "Allocating root glyph cache for size %u", this->fs);
|
||||
Debug(freetype, 3, "Allocating root glyph cache for size {}", this->fs);
|
||||
this->glyph_to_sprite = CallocT<GlyphEntry*>(256);
|
||||
}
|
||||
|
||||
if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) {
|
||||
DEBUG(freetype, 3, "Allocating glyph cache for range 0x%02X00, size %u", GB(key, 8, 8), this->fs);
|
||||
Debug(freetype, 3, "Allocating glyph cache for range 0x{:02X}00, size {}", GB(key, 8, 8), this->fs);
|
||||
this->glyph_to_sprite[GB(key, 8, 8)] = CallocT<GlyphEntry>(256);
|
||||
}
|
||||
|
||||
DEBUG(freetype, 4, "Set glyph for unicode character 0x%04X, size %u", key, this->fs);
|
||||
Debug(freetype, 4, "Set glyph for unicode character 0x{:04X}, size {}", key, this->fs);
|
||||
this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite;
|
||||
this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width;
|
||||
this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].duplicate = duplicate;
|
||||
@@ -467,7 +468,7 @@ void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels)
|
||||
this->height = this->ascender - this->descender;
|
||||
} else {
|
||||
/* Both FT_Set_Pixel_Sizes and FT_Select_Size failed. */
|
||||
DEBUG(freetype, 0, "Font size selection failed. Using FontCache defaults.");
|
||||
Debug(freetype, 0, "Font size selection failed. Using FontCache defaults.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +490,7 @@ static void LoadFreeTypeFont(FontSize fs)
|
||||
case FS_MONO: settings = &_freetype.mono; break;
|
||||
}
|
||||
|
||||
if (StrEmpty(settings->font)) return;
|
||||
if (settings->font.empty()) return;
|
||||
|
||||
if (_library == nullptr) {
|
||||
if (FT_Init_FreeType(&_library) != FT_Err_Ok) {
|
||||
@@ -497,22 +498,23 @@ static void LoadFreeTypeFont(FontSize fs)
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(freetype, 2, "Initialized");
|
||||
Debug(freetype, 2, "Initialized");
|
||||
}
|
||||
|
||||
const char *font_name = settings->font.c_str();
|
||||
FT_Face face = nullptr;
|
||||
|
||||
/* If font is an absolute path to a ttf, try loading that first. */
|
||||
FT_Error error = FT_New_Face(_library, settings->font, 0, &face);
|
||||
FT_Error error = FT_New_Face(_library, font_name, 0, &face);
|
||||
|
||||
#if defined(WITH_COCOA)
|
||||
extern void MacOSRegisterExternalFont(const char *file_path);
|
||||
if (error == FT_Err_Ok) MacOSRegisterExternalFont(settings->font);
|
||||
if (error == FT_Err_Ok) MacOSRegisterExternalFont(font_name);
|
||||
#endif
|
||||
|
||||
if (error != FT_Err_Ok) {
|
||||
/* Check if font is a relative filename in one of our search-paths. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
|
||||
if (!full_font.empty()) {
|
||||
error = FT_New_Face(_library, full_font.c_str(), 0, &face);
|
||||
#if defined(WITH_COCOA)
|
||||
@@ -522,10 +524,10 @@ static void LoadFreeTypeFont(FontSize fs)
|
||||
}
|
||||
|
||||
/* Try loading based on font face name (OS-wide fonts). */
|
||||
if (error != FT_Err_Ok) error = GetFontByFaceName(settings->font, &face);
|
||||
if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face);
|
||||
|
||||
if (error == FT_Err_Ok) {
|
||||
DEBUG(freetype, 2, "Requested '%s', using '%s %s'", settings->font, face->family_name, face->style_name);
|
||||
Debug(freetype, 2, "Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
|
||||
|
||||
/* Attempt to select the unicode character map */
|
||||
error = FT_Select_Charmap(face, ft_encoding_unicode);
|
||||
@@ -555,7 +557,7 @@ static void LoadFreeTypeFont(FontSize fs)
|
||||
FT_Done_Face(face);
|
||||
|
||||
static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
|
||||
ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", settings->font, SIZE_TO_NAME[fs], error);
|
||||
ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, SIZE_TO_NAME[fs], error);
|
||||
return;
|
||||
|
||||
found_face:
|
||||
@@ -616,9 +618,9 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa)
|
||||
if (this->fs == FS_NORMAL && !aa) {
|
||||
for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
|
||||
for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
|
||||
if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
|
||||
if (HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
|
||||
sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR;
|
||||
sprite.data[1 + x + (1 + y) * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF;
|
||||
sprite.data[1 + x + (1 + y) * sprite.width].a = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,9 +214,9 @@ static inline bool GetDrawGlyphShadow(FontSize size)
|
||||
|
||||
/** Settings for a single freetype font. */
|
||||
struct FreeTypeSubSetting {
|
||||
char font[MAX_PATH]; ///< The name of the font, or path to the font.
|
||||
uint size; ///< The (requested) size of the font.
|
||||
bool aa; ///< Whether to do anti aliasing or not.
|
||||
std::string font; ///< The name of the font, or path to the font.
|
||||
uint size; ///< The (requested) size of the font.
|
||||
bool aa; ///< Whether to do anti aliasing or not.
|
||||
|
||||
const void *os_handle = nullptr; ///< Optional native OS font info. Only valid during font search.
|
||||
};
|
||||
|
||||
@@ -1023,7 +1023,7 @@ void ConPrintFramerate()
|
||||
const int count2 = NUM_FRAMERATE_POINTS / 4;
|
||||
const int count3 = NUM_FRAMERATE_POINTS / 1;
|
||||
|
||||
IConsolePrintF(TC_SILVER, "Based on num. data points: %d %d %d", count1, count2, count3);
|
||||
IConsolePrint(TC_SILVER, "Based on num. data points: {} {} {}", count1, count2, count3);
|
||||
|
||||
static const char *MEASUREMENT_NAMES[PFE_MAX] = {
|
||||
"Game loop",
|
||||
@@ -1050,7 +1050,7 @@ void ConPrintFramerate()
|
||||
for (const PerformanceElement *e = rate_elements; e < rate_elements + lengthof(rate_elements); e++) {
|
||||
auto &pf = _pf_data[*e];
|
||||
if (pf.num_valid == 0) continue;
|
||||
IConsolePrintF(TC_GREEN, "%s rate: %.2ffps (expected: %.2ffps)",
|
||||
IConsolePrint(TC_GREEN, "{} rate: {:.2f}fps (expected: {:.2f}fps)",
|
||||
MEASUREMENT_NAMES[*e],
|
||||
pf.GetRate(),
|
||||
pf.expected_rate);
|
||||
@@ -1067,7 +1067,7 @@ void ConPrintFramerate()
|
||||
seprintf(ai_name_buf, lastof(ai_name_buf), "AI %d %s", e - PFE_AI0 + 1, GetAIName(e - PFE_AI0)),
|
||||
name = ai_name_buf;
|
||||
}
|
||||
IConsolePrintF(TC_LIGHT_BLUE, "%s times: %.2fms %.2fms %.2fms",
|
||||
IConsolePrint(TC_LIGHT_BLUE, "{} times: {:.2f}ms {:.2f}ms {:.2f}ms",
|
||||
name,
|
||||
pf.GetAverageDurationMilliseconds(count1),
|
||||
pf.GetAverageDurationMilliseconds(count2),
|
||||
@@ -1076,6 +1076,6 @@ void ConPrintFramerate()
|
||||
}
|
||||
|
||||
if (!printed_anything) {
|
||||
IConsoleWarning("No performance measurements have been taken yet");
|
||||
IConsolePrint(CC_ERROR, "No performance measurements have been taken yet.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
* the GameConfig. If not, remove the Game from the list. */
|
||||
if (_settings_game.game_config != nullptr && _settings_game.game_config->HasScript()) {
|
||||
if (!_settings_game.game_config->ResetInfo(true)) {
|
||||
DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_game.game_config->GetName());
|
||||
Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_game.game_config->GetName());
|
||||
_settings_game.game_config->Change(nullptr);
|
||||
if (Game::instance != nullptr) {
|
||||
delete Game::instance;
|
||||
@@ -182,7 +182,7 @@
|
||||
}
|
||||
if (_settings_newgame.game_config != nullptr && _settings_newgame.game_config->HasScript()) {
|
||||
if (!_settings_newgame.game_config->ResetInfo(false)) {
|
||||
DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName());
|
||||
Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName());
|
||||
_settings_newgame.game_config->Change(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
static bool CheckAPIVersion(const char *api_version)
|
||||
{
|
||||
static const std::set<std::string> versions = { "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "1.12" };
|
||||
static const std::set<std::string> versions = { "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12" };
|
||||
return versions.find(api_version) != versions.end();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ template <> const char *GetClassName<GameInfo, ST_GS>() { return "GSInfo"; }
|
||||
{
|
||||
/* Get the GameInfo */
|
||||
SQUserPointer instance = nullptr;
|
||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of GameInfo to RegisterGame");
|
||||
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, nullptr)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of GameInfo to RegisterGame");
|
||||
GameInfo *info = (GameInfo *)instance;
|
||||
|
||||
SQInteger res = ScriptInfo::Constructor(vm, info);
|
||||
@@ -75,7 +75,7 @@ template <> const char *GetClassName<GameInfo, ST_GS>() { return "GSInfo"; }
|
||||
if (!info->CheckMethod("GetAPIVersion")) return SQ_ERROR;
|
||||
if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR;
|
||||
if (!CheckAPIVersion(info->api_version)) {
|
||||
DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
|
||||
Debug(script, 1, "Loading info.nut from ({}.{}): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
|
||||
return SQ_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ void CDECL strgen_warning(const char *s, ...)
|
||||
va_start(va, s);
|
||||
vseprintf(buf, lastof(buf), s, va);
|
||||
va_end(va);
|
||||
DEBUG(script, 0, "%s:%d: warning: %s", _file, _cur_line, buf);
|
||||
Debug(script, 0, "{}:{}: warning: {}", _file, _cur_line, buf);
|
||||
_warnings++;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ void CDECL strgen_error(const char *s, ...)
|
||||
va_start(va, s);
|
||||
vseprintf(buf, lastof(buf), s, va);
|
||||
va_end(va);
|
||||
DEBUG(script, 0, "%s:%d: error: %s", _file, _cur_line, buf);
|
||||
Debug(script, 0, "{}:{}: error: {}", _file, _cur_line, buf);
|
||||
_errors++;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ void NORETURN CDECL strgen_fatal(const char *s, ...)
|
||||
va_start(va, s);
|
||||
vseprintf(buf, lastof(buf), s, va);
|
||||
va_end(va);
|
||||
DEBUG(script, 0, "%s:%d: FATAL: %s", _file, _cur_line, buf);
|
||||
Debug(script, 0, "{}:{}: FATAL: {}", _file, _cur_line, buf);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ GameStrings *LoadTranslations()
|
||||
basename.erase(e + 1);
|
||||
|
||||
std::string filename = basename + "lang" PATHSEP "english.txt";
|
||||
if (!FioCheckFileExists(filename.c_str() , GAME_DIR)) return nullptr;
|
||||
if (!FioCheckFileExists(filename, GAME_DIR)) return nullptr;
|
||||
|
||||
auto ls = ReadRawLanguageStrings(filename);
|
||||
if (!ls.IsValid()) return nullptr;
|
||||
@@ -249,16 +249,15 @@ GameStrings *LoadTranslations()
|
||||
if (!tar_filename.empty() && (iter = _tar_list[GAME_DIR].find(tar_filename)) != _tar_list[GAME_DIR].end()) {
|
||||
/* The main script is in a tar file, so find all files that
|
||||
* are in the same tar and add them to the langfile scanner. */
|
||||
TarFileList::iterator tar;
|
||||
FOR_ALL_TARS(tar, GAME_DIR) {
|
||||
for (const auto &tar : _tar_filelist[GAME_DIR]) {
|
||||
/* Not in the same tar. */
|
||||
if (tar->second.tar_filename != iter->first) continue;
|
||||
if (tar.second.tar_filename != iter->first) continue;
|
||||
|
||||
/* Check the path and extension. */
|
||||
if (tar->first.size() <= ldir.size() || tar->first.compare(0, ldir.size(), ldir) != 0) continue;
|
||||
if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue;
|
||||
if (tar.first.size() <= ldir.size() || tar.first.compare(0, ldir.size(), ldir) != 0) continue;
|
||||
if (tar.first.compare(tar.first.size() - 4, 4, ".txt") != 0) continue;
|
||||
|
||||
scanner.AddFile(tar->first, 0, tar_filename);
|
||||
scanner.AddFile(tar.first, 0, tar_filename);
|
||||
}
|
||||
} else {
|
||||
/* Scan filesystem */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user