41#define INITDATA(key, type, name) data[key] = dashData_t(type, name)
155 MyGUI::ResourceManager::getInstance().load(
"MyGUI_FontsDash.xml");
179 fmt::format(
"{}: Cannot register dashboard custom input \"{}\", name conflicts with existing one. Ignoring it.",
m_actor->
ar_design_name, name));
185 fmt::format(
"{}: Cannot register dashboard custom input \"{}\", invalid data type.",
m_actor->
ar_design_name, name));
200 for (
int i = 0; i <
data.size(); i++)
202 if (
data[i].name == str)
210 if (
id >= 0 &&
id <
data.size())
212 return data[id].name;
227 std::regex rpm_regex(R
"((\d+)rpm)");
229 if (std::regex_search(input, match, rpm_regex)) {
230 std::string rpm = match[1];
231 return std::atoi(rpm.c_str());
238 std::regex xph_regex(R
"(([km])ph)");
240 if (std::regex_search(input, match, xph_regex)) {
241 return match[1].str()[0];
254 this->filename = filename;
263 Ogre::FileInfoListPtr filelist
264 = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(entry->
resource_group, fmt::format(
"{}*.layout", basename));
266 if (filelist->empty())
277 return filelist->begin()->filename;
303 std::vector<DashCandidateLayout> candidates;
305 for (Ogre::FileInfo& fileinfo : *filelist)
307 candidates.emplace_back(fileinfo.filename);
311 float least_overshoot = std::numeric_limits<float>::max();
DashCandidateLayout* overshoot_candidate =
nullptr;
312 float least_undershoot = -std::numeric_limits<float>::max();
DashCandidateLayout* undershoot_candidate =
nullptr;
313 for (
auto& candidate : candidates)
315 if (candidate.xph == desiredX)
317 float rpm_diff = (float)candidate.
rpm - redlineRPM;
318 if (rpm_diff < 0 && rpm_diff > least_undershoot)
320 least_undershoot = rpm_diff;
321 undershoot_candidate = &candidate;
323 else if (rpm_diff >= 0 && rpm_diff < least_overshoot)
325 least_overshoot = rpm_diff;
326 overshoot_candidate = &candidate;
331 if (overshoot_candidate)
333 return overshoot_candidate->
filename;
335 else if (undershoot_candidate)
338 fmt::format(
"{}: No ideal dashboard found, using one with least RPM undershoot",
m_actor->
ar_design_name));
339 return undershoot_candidate->
filename;
344 fmt::format(
"{}: Selected dashboard has no '{}ph' layouts, ignoring setting",
m_actor->
ar_design_name, desiredX));
345 least_overshoot = std::numeric_limits<float>::max(); overshoot_candidate =
nullptr;
346 least_undershoot = -std::numeric_limits<float>::max(); undershoot_candidate =
nullptr;
347 for (
auto& candidate : candidates)
349 float rpm_diff = (float)candidate.
rpm - redlineRPM;
350 if (rpm_diff < 0 && rpm_diff > least_undershoot)
352 least_undershoot = rpm_diff;
353 undershoot_candidate = &candidate;
355 else if (rpm_diff >= 0 && rpm_diff < least_overshoot)
357 least_overshoot = rpm_diff;
358 overshoot_candidate = &candidate;
362 if (overshoot_candidate)
364 return overshoot_candidate->
filename;
366 else if (undershoot_candidate)
369 fmt::format(
"{}: No ideal dashboard found, using one with least RPM undershoot",
m_actor->
ar_design_name));
370 return undershoot_candidate->
filename;
373 return filelist->begin()->filename;
380 DataStreamPtr ds = ResourceGroupManager::getSingleton().openResource(entry->
fname, entry->
resource_group);
390 bool valid_custom_input =
true;
392 int custom_input_data_type;
395 if (data_type_str ==
"bool") { custom_input_data_type =
DC_BOOL; }
396 else if (data_type_str ==
"float") { custom_input_data_type =
DC_FLOAT; }
397 else if (data_type_str ==
"int") { custom_input_data_type =
DC_INT; }
398 else if (data_type_str ==
"string") { custom_input_data_type =
DC_CHAR; }
401 valid_custom_input =
false;
403 fmt::format(
"Dashboard Custom Input: Invalid data type \"{}\" for \"{}\"", data_type_str, custom_input_name));
406 if (valid_custom_input)
415 catch (Ogre::Exception& e)
417 RoR::LogFormat(
"[RoR|DashBoardManager] Error processing file '%s', message :%s",
418 entry->
fname.c_str(), e.getFullDescription().c_str());
423bool GetGuisettingTextureName(
const std::string& logLabel,
const std::string& matGuisetting,
const std::string& matRg, std::string& outTexname)
425 if (matGuisetting ==
"")
427 LOG(fmt::format(
"[RoR|DashBoard] '{}' not defined in 'guisettings'", logLabel));
431 Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matGuisetting, matRg);
434 LOG(fmt::format(
"[RoR|DashBoard] '{}' '{}' not found", logLabel, matGuisetting));
439 !mat->getTechniques().size() ||
440 !mat->getTechniques()[0]->getPasses().size() ||
441 !mat->getTechniques()[0]->getPasses()[0]->getTextureUnitStates().size() ||
442 mat->getTechniques()[0]->getPasses()[0]->getTextureUnitStates()[0]->getTextureName() ==
"")
444 LOG(fmt::format(
"[RoR|DashBoard] '{}' '{}' has no texture", logLabel, matGuisetting));
448 outTexname = mat->getTechniques()[0]->getPasses()[0]->getTextureUnitStates()[0]->getTextureName();
460 std::string basename, ext, layoutfname, scriptfilename =
"";
461 Ogre::StringUtil::splitBaseFilename(filename, basename, ext);
462 if (ext ==
"dashboard")
468 fmt::format(
"DashboardManager: Could not find dashboard file '{}'", filename));
477 Ogre::FileInfoListPtr filelist
478 = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(entry->
resource_group, fmt::format(
"{}*.resource", basename));
479 for (Ogre::FileInfo& fileinfo : *filelist)
481 MyGUI::ResourceManager::getInstance().load(fileinfo.filename);
486 std::string expected_script_name = fmt::format(
"{}.as", basename);
488 Ogre::ResourceGroupManager::getSingleton().resourceExists(entry->
resource_group, expected_script_name);
490 scriptfilename = expected_script_name;
494 layoutfname = filename;
497 if (layoutfname ==
"")
500 fmt::format(
"{}: Cannot load dashboard '{}' - no applicable layout file found",
m_actor->
ar_design_name, filename));
507 d =
new DashBoard(
this, layoutfname, rttLayer);
524 d =
new DashBoard(
this, layoutfname, rttLayer);
533 d =
new DashBoard(
this, layoutfname, rttLayer);
550 if (scriptfilename !=
"")
564 std::string tachotex;
574 for (
int i = 0; i < link.geometricAnimationCount; i++)
580 const std::string prefixLessName = std::string(link.name).substr(d->
prefix.size());
581 LOG(fmt::format(
"[RoR|DashBoard] per 'guisettings/useMaxRPM', overriding vmax of '{}' to {}", prefixLessName, redlineRPM));
582 anim.
vmax = redlineRPM;
588 std::string speedotex;
598 for (
int i = 0; i < link.geometricAnimationCount; i++)
603 const std::string prefixLessName = std::string(link.name).substr(d->
prefix.size());
639 if (key >=
data.size())
642 switch (
data[key].type)
645 return data[key].data.value_bool ? 1.0f : 0.0f;
647 return (
float)
data[key].data.value_int;
649 return data[key].data.value_float;
659 if (!d->getIsTextureLayer())
661 d->setVisible(visibility);
670 if (d->getIsTextureLayer())
672 d->setVisible(visibility,
false);
699 , mainWidget(nullptr)
700 , rttLayer(_rttLayer)
703 prefix = MyGUI::utility::toString(
this,
"_");
714 MyGUI::LayoutManager::getInstance().unloadLayout(
widgets);
716 MyGUI::ResourceManager::getInstance().removeByName(
filename);
728 for (
size_t i = 0; i <
controls.size(); i++)
732 controls[i].widget->setVisible(enabled);
756 for (
size_t i = 0; i <
controls.size(); i++)
767 state = (val >
controls[i].graphicalAnimation.conditionArgument);
772 state = (val <
controls[i].graphicalAnimation.conditionArgument);
786 controls[i].img->setImageTexture(String(
controls[i].graphicalAnimation.texture) +
"-on.png");
790 controls[i].img->setImageTexture(String(
controls[i].graphicalAnimation.texture) +
"-off.png");
797 String fn = String(
controls[i].graphicalAnimation.texture) + String(
"-") +
TOSTRING((
int)val) + String(
".png");
799 controls[i].img->setImageTexture(fn);
806 if (strlen(
controls[i].graphicalAnimation.format) == 0)
808 s = Ogre::StringConverter::toString(val);
813 sprintf(tmp,
controls[i].graphicalAnimation.format, val);
816 if (strcmp(tmp,
controls[i].graphicalAnimation.format_neg_zero) == 0)
818 sprintf(tmp,
controls[i].graphicalAnimation.format, 0.f);
821 s = MyGUI::UString(tmp);
829 controls[i].txt->setCaption(MyGUI::UString(val));
836 controls[i].img->setImageTexture(MyGUI::UString(val));
840 float finalHorizontalTranslation = 0,
841 finalVerticalTranslation = 0;
842 for (
int animIdx = 0; animIdx <
controls[i].geometricAnimationCount; animIdx++)
852 float angle = (val - animation.
vmin) * (animation.
wmax - animation.
wmin) / (animation.
vmax - animation.
vmin) + animation.
wmin;
855 if (angle < animation.
wmin)
856 angle = animation.
wmin;
857 else if (angle > animation.
wmax)
858 angle = animation.
wmax;
860 controls[i].rotImg->setAngle(Ogre::Degree(angle).valueRadians());
866 float scale = (val - animation.
vmin) * (animation.
wmax - animation.
wmin) / (animation.
vmax - animation.
vmin) + animation.
wmin;
870 finalVerticalTranslation -= scale;
879 finalHorizontalTranslation -= scale;
891 float translation = (val - animation.
vmin) * (animation.
wmax - animation.
wmin) / (animation.
vmax - animation.
vmin) + animation.
wmin;
894 finalVerticalTranslation -= translation;
896 finalVerticalTranslation += translation;
898 finalHorizontalTranslation -= translation;
900 finalHorizontalTranslation += translation;
904 controls[i].widget->setPosition(
controls[i].initialPosition.left + finalHorizontalTranslation,
controls[i].initialPosition.top + finalVerticalTranslation);
918 mainWidget->setSize(tex->getWidth(), tex->getHeight());
922 MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize();
930 bool stretch,
bool anchor_near,
bool anchor_far,
float scale,
int& out_pos,
int& out_size)
932 const float far_margin =
static_cast<float>(parent_orig - (pos + size));
935 out_pos =
static_cast<int>(std::round(pos * scale));
936 out_size = parent_new - out_pos -
static_cast<int>(std::round(far_margin * scale));
940 out_size =
static_cast<int>(std::round(size * scale));
941 out_pos = parent_new -
static_cast<int>(std::round(far_margin * scale)) - out_size;
943 else if (anchor_near)
945 out_pos =
static_cast<int>(std::round(pos * scale));
946 out_size =
static_cast<int>(std::round(size * scale));
950 const float center_offset = (pos + size / 2.f) - (parent_orig / 2.f);
951 out_size =
static_cast<int>(std::round(size * scale));
952 out_pos =
static_cast<int>(std::round((parent_new / 2.f) + (center_offset * scale) - (out_size / 2.f)));
958 MyGUI::EnumeratorWidgetPtr e = parent->getEnumerator();
961 MyGUI::Widget*
w = e.current();
963 origin.
coord =
w->getCoord();
964 MyGUI::TextBox* txt =
w->castType<MyGUI::TextBox>(
false);
976 MyGUI::EnumeratorWidgetPtr e = parent->getEnumerator();
979 MyGUI::Widget*
w = e.current();
986 const MyGUI::Align align =
w->getAlign();
989 MyGUI::IntCoord coord;
991 align.isHStretch(), align.isLeft(), align.isRight(),
m_ui_scale, coord.left, coord.width);
993 align.isVStretch(), align.isTop(), align.isBottom(),
m_ui_scale, coord.top, coord.height);
998 w->castType<MyGUI::TextBox>()->setFontHeight(
static_cast<int>(std::round(origin.
font_height *
m_ui_scale)));
1018 ctrl.initialSize = ctrl.widget->getSize();
1019 ctrl.initialPosition = ctrl.widget->getPosition();
1022 ctrl.rotImg->setCenter(MyGUI::IntPoint(ctrl.widget->getWidth() * 0.5f, ctrl.widget->getHeight() * 0.5f));
1027bool DashBoard::parseLink(std::string& linkArgs,
int& linkID,
char& condition,
float& conditionArgument,
const std::string& filename,
const std::string& name)
1031 String linkName =
"";
1032 if (linkArgs.empty())
1034 LOG(
"Dashboard (" +
filename +
"/" + name +
"): empty Link");
1039 if (linkArgs.find(
">") != linkArgs.npos)
1041 Ogre::StringVector args = Ogre::StringUtil::split(linkArgs,
">");
1042 if (args.size() == 2)
1045 conditionArgument = StringConverter::parseReal(args[1]);
1050 LOG(
"Dashboard (" +
filename +
"/" + name +
"): error in conditional Link: " + linkArgs);
1054 else if (linkArgs.find(
"<") != linkArgs.npos)
1056 Ogre::StringVector args = Ogre::StringUtil::split(linkArgs,
"<");
1057 if (args.size() == 2)
1060 conditionArgument = StringConverter::parseReal(args[1]);
1065 LOG(
"Dashboard (" +
filename +
"/" + name +
"): error in conditional Link: " + linkArgs);
1072 conditionArgument = 0;
1073 linkName = linkArgs;
1078 if (linkIDResult < 0)
1080 LOG(
"Dashboard (" +
filename +
"/" + name +
"): unknown Link: " + linkName);
1084 linkID = linkIDResult;
1090 std::string name =
w->getName();
1091 std::string debug =
w->getUserString(
"debug");
1094 w->setUserString(
"interactive",
"0");
1098 w->setVisible(
false);
1103 if (name.size() >
prefix.size())
1105 std::string prefixLessName = name.substr(
prefix.size());
1106 if (prefixLessName ==
"_Main")
1114 if (prefixLessName ==
"DEBUG")
1116 w->setVisible(
false);
1122 memset(&ctrl, 0,
sizeof(ctrl));
1126 float conditionArgument;
1136 std::string graphicalAnimationUsed =
"";
1141 std::string animNumStr =
"anim";
1142 std::string linkNumStr =
"link";
1143 std::string minNumStr =
"min";
1144 std::string maxNumStr =
"max";
1145 std::string vminNumStr =
"vmin";
1146 std::string vmaxNumStr =
"vmax";
1147 std::string textureNumStr =
"texture";
1148 std::string formatNumStr =
"format";
1149 std::string directionNumStr =
"direction";
1151 std::string anim =
w->getUserString(animNumStr);
1152 std::string linkArgs;
1155 bool linkIDForVisibilitySet =
false;
1158 linkArgs =
w->getUserString(linkNumStr);
1161 if (!linkArgs.empty())
1164 bool graphicalAnimation =
false,
1165 graphicalAnimationAlreadySet =
false,
1166 geometricAnimation =
false;
1167 if (anim ==
"rotate")
1170 geometricAnimation =
true;
1172 else if (anim ==
"scale")
1175 geometricAnimation =
true;
1177 else if (anim ==
"translate")
1180 geometricAnimation =
true;
1182 else if (anim ==
"series")
1185 graphicalAnimation =
true;
1186 if (graphicalAnimationUsed ==
"")
1187 graphicalAnimationUsed = anim;
1189 graphicalAnimationAlreadySet =
true;
1191 else if (anim ==
"textcolor" || anim ==
"textcolour")
1194 graphicalAnimation =
true;
1195 if (graphicalAnimationUsed ==
"")
1196 graphicalAnimationUsed = anim;
1198 graphicalAnimationAlreadySet =
true;
1200 else if (anim ==
"textformat")
1203 graphicalAnimation =
true;
1204 if (graphicalAnimationUsed ==
"")
1205 graphicalAnimationUsed = anim;
1207 graphicalAnimationAlreadySet =
true;
1209 else if (anim ==
"textstring")
1212 graphicalAnimation =
true;
1213 if (graphicalAnimationUsed ==
"")
1214 graphicalAnimationUsed = anim;
1216 graphicalAnimationAlreadySet =
true;
1218 else if (anim ==
"lamp")
1221 graphicalAnimation =
true;
1222 if (graphicalAnimationUsed ==
"")
1223 graphicalAnimationUsed = anim;
1225 graphicalAnimationAlreadySet =
true;
1227 else if (anim ==
"imagetexture")
1230 graphicalAnimation =
true;
1231 if (graphicalAnimationUsed ==
"")
1232 graphicalAnimationUsed = anim;
1234 graphicalAnimationAlreadySet =
true;
1238 LOG(
"Dashboard (" +
filename +
"/" + name +
"): Unknown animation \"" + anim +
"\".");
1242 if (graphicalAnimationAlreadySet)
1244 LOG(
"Dashboard (" +
filename +
"/" + name +
"): Animations \"" + anim +
"\" and \"" + graphicalAnimationUsed +
"\" can't be used at the same time.");
1253 strncpy(ctrl.
name, name.c_str(),
sizeof ctrl.
name);
1255 bool linkParsed =
parseLink(linkArgs, linkID, condition, conditionArgument,
filename, name);
1260 if (!linkIDForVisibilitySet)
1263 linkIDForVisibilitySet =
true;
1266 if (graphicalAnimation)
1273 String texture =
w->getUserString(textureNumStr);
1274 if (!texture.empty())
1277 String format =
w->getUserString(formatNumStr);
1278 if (!format.empty())
1284 ctrl.
img =
w->castType<MyGUI::ImageBox>(
false);
1287 LOG(
"Dashboard (" +
filename +
"/" + name +
"): series anim must use the ImageBox Control");
1293 ctrl.
txt =
w->castType<MyGUI::TextBox>(
false);
1296 LOG(
"Dashboard (" +
filename +
"/" + name +
"): textcolor anim must use the TextBox Control");
1302 ctrl.
txt =
w->castType<MyGUI::TextBox>(
false);
1305 LOG(
"Dashboard (" +
filename +
"/" + name +
"): textformat anim must use the TextBox Control");
1318 ctrl.
txt =
w->castType<MyGUI::TextBox>(
false);
1321 LOG(
"Dashboard (" +
filename +
"/" + name +
"): textstring anim must use the TextBox Control");
1327 ctrl.
img =
w->castType<MyGUI::ImageBox>(
false);
1330 LOG(
"Dashboard (" +
filename +
"/" + name +
"): lamp anim must use the ImageBox Control");
1336 ctrl.
img =
w->castType<MyGUI::ImageBox>(
false);
1339 LOG(
"Dashboard (" +
filename +
"/" + name +
"): imagetexture anim must use the ImageBox Control");
1344 else if (geometricAnimation)
1354 geometricAnim.
linkID = linkID;
1360 geometricAnim.
wmin = StringConverter::parseReal(
w->getUserString(minNumStr));
1361 geometricAnim.
wmax = StringConverter::parseReal(
w->getUserString(maxNumStr));
1362 geometricAnim.
vmin = StringConverter::parseReal(
w->getUserString(vminNumStr));
1363 geometricAnim.
vmax = StringConverter::parseReal(
w->getUserString(vmaxNumStr));
1365 String direction =
w->getUserString(directionNumStr);
1366 if (direction ==
"right")
1368 else if (direction ==
"left")
1370 else if (direction ==
"down")
1372 else if (direction ==
"up")
1374 else if (!direction.empty())
1376 LOG(
"Dashboard (" +
filename +
"/" + name +
"): unknown direction: " + direction);
1384 ctrl.
rotImg =
w->getSubWidgetMain()->castType<MyGUI::RotatingSkin>(
false);
1387 LOG(
"Dashboard (" +
filename +
"/" + name +
"): Rotating controls must use the RotatingSkin");
1392 ctrl.
rotImg->setCenter(MyGUI::IntPoint(
w->getWidth() * 0.5f,
w->getHeight() * 0.5f));
1398 LOG(
"Dashboard (" +
filename +
"/" + name +
"): direction empty: scale needs a direction");
1406 LOG(
"Dashboard (" +
filename +
"/" + name +
"): direction empty: translate needs a direction");
1415 animNumStr = fmt::format(
"anim{}", animNum);
1416 linkNumStr = fmt::format(
"link{}", animNum);
1417 minNumStr = fmt::format(
"min{}", animNum);
1418 maxNumStr = fmt::format(
"max{}", animNum);
1419 vminNumStr = fmt::format(
"vmin{}", animNum);
1420 vmaxNumStr = fmt::format(
"vmax{}", animNum);
1421 textureNumStr = fmt::format(
"texture{}", animNum);
1422 formatNumStr = fmt::format(
"format{}", animNum);
1423 directionNumStr = fmt::format(
"direction{}", animNum);
1424 anim =
w->getUserString(animNumStr);
1432 linkArgs =
w->getUserString(
"link");
1434 if (!linkArgs.empty())
1436 bool linkParsed =
parseLink(linkArgs, linkID, condition, conditionArgument,
filename, name);
1451 MyGUI::EnumeratorWidgetPtr e =
w->getEnumerator();
1462 for (MyGUI::VectorWidgetPtr::iterator iter =
widgets.begin(); iter !=
widgets.end(); ++iter)
1489 for (MyGUI::VectorWidgetPtr::iterator iter =
widgets.begin(); iter !=
widgets.end(); ++iter)
1491 (*iter)->setVisible(v);
Central state/object manager and communications hub.
void LOG(const char *msg)
Legacy alias - formerly a macro.
#define BITMASK_IS_1(VAR, FLAGS)
#define BITMASK_IS_0(VAR, FLAGS)
A database of user-installed content alias 'mods' (vehicles, terrains...)
bool GetGuisettingTextureName(const std::string &logLabel, const std::string &matGuisetting, const std::string &matRg, std::string &outTexname)
constexpr int DASHTAG_RPM_NONE
constexpr char DASHTAG_XPH_NONE
static char DashXPH(const std::string &input)
const float DASH_SMOOTHING
#define INITDATA(key, type, name)
static void ScaleDashWidgetAxis(int pos, int size, int parent_orig, int parent_new, bool stretch, bool anchor_near, bool anchor_far, float scale, int &out_pos, int &out_size)
static int DashRPM(const std::string &input)
#define DD_MAX_GEOMETRIC_ANIMATIONS
float ar_guisettings_speedo_max_kph
Ogre::String ar_design_name
Name of the vehicle/machine/object this actor represents.
std::string ar_guisettings_speedo_material
Used on 'renderdash'.
std::string ar_guisettings_tacho_material
Used on 'renderdash'.
std::string ar_guisettings_help_material
Used on 'renderdash'.
bool ar_guisettings_use_engine_max_rpm
ActorType ar_driveable
Sim attr; marks vehicle type and features.
Ogre::String fname
filename
Ogre::String resource_group
Resource group of the loaded bundle. Empty if not loaded yet.
CacheEntryPtr FindEntryByFilename(RoR::LoaderType type, bool partial, const std::string &_filename_maybe_bundlequalified)
Returns NULL if none found; "Bundle-qualified" format also specifies the ZIP/directory in modcache,...
void LoadResource(CacheEntryPtr &t)
Loads the associated resource bundle if not already done.
@ CONSOLE_MSGTYPE_ACTOR
Parsing/spawn/simulation messages for actors.
@ CONSOLE_MSGTYPE_INFO
Generic message.
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
void loadLayoutInternal()
MyGUI::WindowPtr mainWidget
void applyUiScaleRecursive(MyGUI::Widget *parent, MyGUI::IntSize parent_orig_size, MyGUI::IntSize parent_new_size)
void setVisible(bool visible, bool smooth=true)
void snapshotWidgetOriginsRecursive(MyGUI::Widget *parent)
float getSmoothNumeric(int linkID, float &lastVal)
bool parseLink(std::string &linkArgs, int &linkID, char &condition, float &conditionArgument, const std::string &filename, const std::string &name)
float m_ui_scale
Also applies to pixel values of 'scale' and 'translate' animations.
void applyUiScale()
Reads cvar 'ui_scale_factor'; only affects screen dashboards (not RTT)
DashBoard(DashBoardManager *manager, Ogre::String filename, RTTLayer *_rttLayer)
MyGUI::VectorWidgetPtr widgets
std::vector< layoutLink_t > controls
std::map< MyGUI::Widget *, WidgetOrigin > m_widget_origins
Unscaled coords as loaded from layout; empty for RTT dashboards.
MyGUI::IntSize m_main_origin_size
Size of mainWidget when m_widget_origins were recorded.
DashBoardManager * manager
void loadLayoutRecursive(MyGUI::WidgetPtr ptr)
void applyUiScale()
Reads cvar 'ui_scale_factor'; only affects screen dashboards (not RTT)
void setVisible(bool visibility)
std::vector< dashData_t > data
std::string determineLayoutFromDashboardMod(CacheEntryPtr &entry, std::string const &basename, BitMask_t loaddashboardFlags)
int getLinkIDForName(Ogre::String &str)
void setVisible3d(bool visibility)
void loadDashboardModDetails(CacheEntryPtr &entry)
void setChar(int key, const char *val)
std::string determineTruckLayoutFromDashboardMod(Ogre::FileInfoListPtr &filelist)
int registerCustomInput(Ogre::String name, int dataType)
virtual ~DashBoardManager() override
std::string getLinkNameForID(DashData id)
std::vector< DashBoard * > m_dashboards
DashBoardManager(ActorPtr actor)
DashBoard * loadDashBoard(const std::string &filename, BitMask_t flags, RTTLayer *rttLayer)
float getNumeric(int key)
int registeredCustomInputs
float getShiftUpRPM() const
Shift up RPM ('engine' attr #2)
RTTLayerManager & GetRttLayerManager()
float GetUiScaleFactor() const
Reads cvar 'ui_scale_factor', clamped to sane range.
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
Ogre::String GetResourceGroup()
RTT texture 'slot' within MyGUI system; we can only create them, not destroy, so we reuse.
const std::string & getTextureName() const
void RecycleRttLayer(RTTLayer *obj)
@ TRUCK
its a truck (or other land vehicle)
@ AIRPLANE
its an airplane
@ MSG_APP_LOAD_SCRIPT_REQUESTED
Payload = RoR::LoadScriptRequest* (owner)
static const float DEFAULT_SPEEDO_MAX_KPH
@ ACTOR
Defined in truck file under 'scripts', contains global variable BeamClass@ thisActor.
GUIManager * GetGuiManager()
GameContext * GetGameContext()
CacheSystem * GetCacheSystem()
CVar * gfx_speedo_imperial
@ DD_AEROENGINE_THROTTLE_4
@ DD_CUSTOM_LIGHT6
custom light 6 on
@ DD_CUSTOM_LIGHT7
custom light 7 on
@ DD_CUSTOM_LIGHT10
custom light 10 on
@ DD_CUSTOM_LIGHT2
custom light 2 on
@ DD_CUSTOM_LIGHT4
custom light 4 on
@ DD_GUISETTING_TACHO
(char) Tacho texture name - from 'guisettings' section of truck file.
@ DD_ENGINE_NUM_GEAR
current gear
@ DD_LIGHTS_LEGACY
Alias of 'sidelights'.
@ DD_GUISETTING_SPEEDO_KPH
(float) Like DD_ENGINE_SPEEDO_KPH, but if 'speedoTexture' and 'speedoMax' in 'guisettings' are set,...
@ DD_ENGINE_AUTOGEAR_STRING
string like "<current gear>/<max gear>"
@ DD_GUISETTING_HELP
(char) Help texture name - from 'guisettings' section of truck file.
@ DD_GUISETTING_TACHO_RPM
(float) Like DD_ENGINE_RPM, but if 'tachoTexture' and 'useMaxRPM' in 'guisettings' is set,...
@ DD_PARKINGBRAKE
chassis pitch
@ DD_AEROENGINE_THROTTLE_2
@ DD_CUSTOM_LIGHT9
custom light 9 on
@ DD_SIGNAL_WARNING
The warning-blink indicator is lit.
@ DD_CUSTOM_LIGHT3
custom light 3 on
@ DD_CRUISECONTROL_ACTIVE
ties locked
@ DD_SIGNAL_TURNLEFT
Left blinker is lit.
@ DD_ENGINE_SPEEDO_MPH
speedo in kilometer per hour
@ DD_ENGINE_IGNITION
turbo gauge
@ DD_CUSTOM_LIGHT8
custom light 8 on
@ DD_AEROENGINE_THROTTLE_5
@ DD_ENGINE_GEAR
clutch warning lamp
@ DD_AEROENGINE_THROTTLE_0
@ DD_LOCKED
parking brake status
@ DD_ENGINE_AUTO_GEAR
string like "P R N G"
@ DD_SIGNAL_TURNRIGHT
Right blinker is lit.
@ DD_CUSTOM_LIGHT5
custom light 5 on
@ DD_ENGINE_CLUTCH_WARNING
battery lamp
@ DD_LOW_PRESSURE
locked lamp
@ DD_ENGINE_TURBO
speedo in miles per hour
@ DD_ENGINE_CLUTCH
automatic gear
@ DD_GUISETTING_SPEEDO
(char) Speedo texture name - from 'guisettings' section of truck file.
@ DD_CUSTOM_LIGHT1
custom light 1 on
@ DD_TRACTIONCONTROL_MODE
low pressure
@ DD_AEROENGINE_THROTTLE_3
@ DD_AEROENGINE_THROTTLE_1
@ LOADDASHBOARD_RTT_TEXTURE
Will be drawn to texture. Unless STACKABLE, it prevents the default dashboard from loading.
@ LOADDASHBOARD_RENDERDASH
Will be drawn to texture in classic 'renderdash' format. Ignores STACKABLE flag.
@ LOADDASHBOARD_SCREEN_HUD
Will be drawn to screen. Unless STACKABLE, it prevents the default dashboard from loading.
@ LOADDASHBOARD_STACKABLE
Allows loading multiple dashboards at once (by default there's only one for screen and one for RTT).
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
void replaceString(std::string &str, std::string searchString, std::string replaceString)
DashCandidateLayout(const std::string &filename)
char format_neg_zero[255]
Test for undesired '-0.0' on display. Only for link type "format". Empty if not applicable.
layoutGeometricAnimation_t geometricAnimations[DD_MAX_GEOMETRIC_ANIMATIONS]
MyGUI::IntSize initialSize
MyGUI::IntPoint initialPosition
MyGUI::RotatingSkin * rotImg
layoutGraphicalAnimation_t graphicalAnimation
int geometricAnimationCount
bool isTokKeyword(int offset=0) const
std::string getTokKeyword(int offset=0) const
bool endOfFile(int offset=0) const
std::string getTokString(int offset=0) const
static const BitMask_t OPTION_ALLOW_SLASH_COMMENTS
Allow comments starting with //.
virtual void loadFromDataStream(Ogre::DataStreamPtr datastream, BitMask_t options=0)
static const BitMask_t OPTION_ALLOW_NAKED_STRINGS
Allow strings without quotes, for backwards compatibility.
std::string lsr_filename
Load from resource ('.as' file or '.gadget' file); If buffer is supplied, use this as display name on...
ScriptCategory lsr_category
ActorInstanceID_t lsr_associated_actor
For ScriptCategory::ACTOR.
Unified game event system - all requests and state changes are reported using a message.