Merge branch 'jgrpp' into jgrpp-nrt
This commit is contained in:
@@ -48,6 +48,9 @@ struct LoadCheckData {
|
|||||||
struct LoggedAction *gamelog_action; ///< Gamelog actions
|
struct LoggedAction *gamelog_action; ///< Gamelog actions
|
||||||
uint gamelog_actions; ///< Number of gamelog actions
|
uint gamelog_actions; ///< Number of gamelog actions
|
||||||
|
|
||||||
|
bool want_debug_log_data = false;
|
||||||
|
std::string debug_log_data;
|
||||||
|
|
||||||
LoadCheckData() : error_data(nullptr), grfconfig(nullptr),
|
LoadCheckData() : error_data(nullptr), grfconfig(nullptr),
|
||||||
grf_compatibility(GLC_NOT_FOUND), gamelog_action(nullptr), gamelog_actions(0)
|
grf_compatibility(GLC_NOT_FOUND), gamelog_action(nullptr), gamelog_actions(0)
|
||||||
{
|
{
|
||||||
|
@@ -67,6 +67,8 @@ void LoadCheckData::Clear()
|
|||||||
this->gamelog_actions = 0;
|
this->gamelog_actions = 0;
|
||||||
|
|
||||||
ClearGRFConfigList(&this->grfconfig);
|
ClearGRFConfigList(&this->grfconfig);
|
||||||
|
|
||||||
|
this->debug_log_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Load game/scenario with optional content download */
|
/** Load game/scenario with optional content download */
|
||||||
|
@@ -36,6 +36,8 @@ byte _support8bpp;
|
|||||||
CursorVars _cursor;
|
CursorVars _cursor;
|
||||||
bool _ctrl_pressed; ///< Is Ctrl pressed?
|
bool _ctrl_pressed; ///< Is Ctrl pressed?
|
||||||
bool _shift_pressed; ///< Is Shift pressed?
|
bool _shift_pressed; ///< Is Shift pressed?
|
||||||
|
bool _invert_ctrl;
|
||||||
|
bool _invert_shift;
|
||||||
byte _fast_forward;
|
byte _fast_forward;
|
||||||
bool _left_button_down; ///< Is left mouse button pressed?
|
bool _left_button_down; ///< Is left mouse button pressed?
|
||||||
bool _left_button_clicked; ///< Is left mouse button clicked?
|
bool _left_button_clicked; ///< Is left mouse button clicked?
|
||||||
|
@@ -56,6 +56,8 @@ extern byte _support8bpp;
|
|||||||
extern CursorVars _cursor;
|
extern CursorVars _cursor;
|
||||||
extern bool _ctrl_pressed; ///< Is Ctrl pressed?
|
extern bool _ctrl_pressed; ///< Is Ctrl pressed?
|
||||||
extern bool _shift_pressed; ///< Is Shift pressed?
|
extern bool _shift_pressed; ///< Is Shift pressed?
|
||||||
|
extern bool _invert_ctrl;
|
||||||
|
extern bool _invert_shift;
|
||||||
extern byte _fast_forward;
|
extern byte _fast_forward;
|
||||||
|
|
||||||
extern bool _left_button_down;
|
extern bool _left_button_down;
|
||||||
@@ -73,6 +75,7 @@ extern Palette _cur_palette; ///< Current palette
|
|||||||
void HandleKeypress(uint keycode, WChar key);
|
void HandleKeypress(uint keycode, WChar key);
|
||||||
void HandleTextInput(const char *str, bool marked = false, const char *caret = nullptr, const char *insert_location = nullptr, const char *replacement_end = nullptr);
|
void HandleTextInput(const char *str, bool marked = false, const char *caret = nullptr, const char *insert_location = nullptr, const char *replacement_end = nullptr);
|
||||||
void HandleCtrlChanged();
|
void HandleCtrlChanged();
|
||||||
|
void HandleShiftChanged();
|
||||||
void HandleMouseEvents();
|
void HandleMouseEvents();
|
||||||
void UpdateWindows();
|
void UpdateWindows();
|
||||||
|
|
||||||
|
@@ -59,6 +59,8 @@ void ShowEstimatedCostOrIncome(Money cost, int x, int y);
|
|||||||
void ShowExtraViewPortWindow(TileIndex tile = INVALID_TILE);
|
void ShowExtraViewPortWindow(TileIndex tile = INVALID_TILE);
|
||||||
void ShowExtraViewPortWindowForTileUnderCursor();
|
void ShowExtraViewPortWindowForTileUnderCursor();
|
||||||
|
|
||||||
|
void ShowModifierKeyToggleWindow();
|
||||||
|
|
||||||
/* bridge_gui.cpp */
|
/* bridge_gui.cpp */
|
||||||
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type);
|
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type);
|
||||||
|
|
||||||
|
@@ -490,6 +490,7 @@ STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Fully zoomed in
|
|||||||
STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Default zoom screenshot
|
STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Default zoom screenshot
|
||||||
STR_ABOUT_MENU_GIANT_SCREENSHOT :Whole map screenshot
|
STR_ABOUT_MENU_GIANT_SCREENSHOT :Whole map screenshot
|
||||||
STR_ABOUT_MENU_SHOW_FRAMERATE :Show frame rate
|
STR_ABOUT_MENU_SHOW_FRAMERATE :Show frame rate
|
||||||
|
STR_ABOUT_MENU_SHOW_TOGGLE_MODIFIER_KEYS :Modifier key window
|
||||||
STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD'
|
STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD'
|
||||||
STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner
|
STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner
|
||||||
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toggle bounding boxes
|
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toggle bounding boxes
|
||||||
@@ -6186,3 +6187,9 @@ STR_SCHDISPATCH_SUMMARY_L2 :{BLACK}This sch
|
|||||||
STR_SCHDISPATCH_SUMMARY_L3 :{BLACK}Maximum delay of {STRING3} is allowed before the slot is skipped.
|
STR_SCHDISPATCH_SUMMARY_L3 :{BLACK}Maximum delay of {STRING3} is allowed before the slot is skipped.
|
||||||
STR_SCHDISPATCH_SUMMARY_NOT_ENABLED :{BLACK}This schedule is not active.
|
STR_SCHDISPATCH_SUMMARY_NOT_ENABLED :{BLACK}This schedule is not active.
|
||||||
|
|
||||||
|
# Modifier key toggle window
|
||||||
|
STR_MODIFIER_KEY_TOGGLE_CAPTION :{WHITE}Modifier keys
|
||||||
|
STR_SHIFT_KEY_NAME :{BLACK}Shift
|
||||||
|
STR_CTRL_KEY_NAME :{BLACK}Ctrl
|
||||||
|
STR_MODIFIER_TOGGLE_SHIFT_TOOLTIP :{BLACK}Click to invert state of Shift key
|
||||||
|
STR_MODIFIER_TOGGLE_CTRL_TOOLTIP :{BLACK}Click to invert state of Ctrl key
|
||||||
|
@@ -1339,3 +1339,88 @@ void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallback
|
|||||||
|
|
||||||
new QueryWindow(&_query_desc, caption, message, parent, callback);
|
new QueryWindow(&_query_desc, caption, message, parent, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const NWidgetPart _modifier_key_toggle_widgets[] = {
|
||||||
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||||
|
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_MODIFIER_KEY_TOGGLE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
|
||||||
|
NWidget(WWT_SHADEBOX, COLOUR_GREY),
|
||||||
|
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||||
|
EndContainer(),
|
||||||
|
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||||
|
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
|
||||||
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(2, 0, 2),
|
||||||
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MKT_SHIFT), SetMinimalSize(78, 12), SetFill(1, 0),
|
||||||
|
SetDataTip(STR_SHIFT_KEY_NAME, STR_MODIFIER_TOGGLE_SHIFT_TOOLTIP),
|
||||||
|
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_MKT_CTRL), SetMinimalSize(78, 12), SetFill(1, 0),
|
||||||
|
SetDataTip(STR_CTRL_KEY_NAME, STR_MODIFIER_TOGGLE_CTRL_TOOLTIP),
|
||||||
|
EndContainer(),
|
||||||
|
NWidget(NWID_SPACER), SetMinimalSize(0, 2),
|
||||||
|
EndContainer(),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ModifierKeyToggleWindow : Window {
|
||||||
|
ModifierKeyToggleWindow(WindowDesc *desc, WindowNumber window_number) :
|
||||||
|
Window(desc)
|
||||||
|
{
|
||||||
|
this->InitNested(window_number);
|
||||||
|
this->UpdateButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
~ModifierKeyToggleWindow()
|
||||||
|
{
|
||||||
|
_invert_shift = false;
|
||||||
|
_invert_ctrl = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateButtons()
|
||||||
|
{
|
||||||
|
this->SetWidgetLoweredState(WID_MKT_SHIFT, _shift_pressed);
|
||||||
|
this->SetWidgetLoweredState(WID_MKT_CTRL, _ctrl_pressed);
|
||||||
|
this->SetDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
EventState OnCTRLStateChange() override
|
||||||
|
{
|
||||||
|
this->UpdateButtons();
|
||||||
|
return ES_NOT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnShiftStateChange() override
|
||||||
|
{
|
||||||
|
this->UpdateButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnClick(Point pt, int widget, int click_count) override
|
||||||
|
{
|
||||||
|
switch (widget) {
|
||||||
|
case WID_MKT_SHIFT:
|
||||||
|
_invert_shift = !_invert_shift;
|
||||||
|
UpdateButtons();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WID_MKT_CTRL:
|
||||||
|
_invert_ctrl = !_invert_ctrl;
|
||||||
|
UpdateButtons();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||||
|
{
|
||||||
|
if (!gui_scope) return;
|
||||||
|
this->UpdateButtons();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static WindowDesc _modifier_key_toggle_desc(
|
||||||
|
WDP_AUTO, "modifier_key_toggle", 0, 0,
|
||||||
|
WC_MODIFIER_KEY_TOGGLE, WC_NONE,
|
||||||
|
WDF_NO_FOCUS,
|
||||||
|
_modifier_key_toggle_widgets, lengthof(_modifier_key_toggle_widgets)
|
||||||
|
);
|
||||||
|
|
||||||
|
void ShowModifierKeyToggleWindow()
|
||||||
|
{
|
||||||
|
AllocateWindowDescFront<ModifierKeyToggleWindow>(&_modifier_key_toggle_desc, 0);
|
||||||
|
}
|
||||||
|
@@ -281,7 +281,7 @@ static void WriteSavegameInfo(const char *name)
|
|||||||
|
|
||||||
GamelogInfo(_load_check_data.gamelog_action, _load_check_data.gamelog_actions, &last_ottd_rev, &ever_modified, &removed_newgrfs);
|
GamelogInfo(_load_check_data.gamelog_action, _load_check_data.gamelog_actions, &last_ottd_rev, &ever_modified, &removed_newgrfs);
|
||||||
|
|
||||||
char buf[8192];
|
char buf[65536];
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
p += seprintf(p, lastof(buf), "Name: %s\n", name);
|
p += seprintf(p, lastof(buf), "Name: %s\n", name);
|
||||||
const char *type = "";
|
const char *type = "";
|
||||||
@@ -323,6 +323,40 @@ static void WriteSavegameInfo(const char *name)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WriteSavegameDebugData(const char *name)
|
||||||
|
{
|
||||||
|
char *buf = MallocT<char>(4096);
|
||||||
|
char *buflast = buf + 4095;
|
||||||
|
char *p = buf;
|
||||||
|
auto bump_size = [&]() {
|
||||||
|
size_t offset = p - buf;
|
||||||
|
size_t new_size = buflast - buf + 1 + 4096;
|
||||||
|
buf = ReallocT<char>(buf, new_size);
|
||||||
|
buflast = buf + new_size - 1;
|
||||||
|
p = buf + offset;
|
||||||
|
};
|
||||||
|
p += seprintf(p, buflast, "Name: %s\n", name);
|
||||||
|
if (_load_check_data.debug_log_data.size()) {
|
||||||
|
p += seprintf(p, buflast, "%u bytes of debug data in savegame\n", (uint) _load_check_data.debug_log_data.size());
|
||||||
|
std::string buffer = _load_check_data.debug_log_data;
|
||||||
|
ProcessLineByLine(const_cast<char *>(buffer.data()), [&](const char *line) {
|
||||||
|
if (buflast - p <= 1024) bump_size();
|
||||||
|
p += seprintf(p, buflast, "> %s\n", line);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
p += seprintf(p, buflast, "No debug data in savegame\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ShowInfo put output to stderr, but version information should go
|
||||||
|
* to stdout; this is the only exception */
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
printf("%s\n", buf);
|
||||||
|
#else
|
||||||
|
ShowInfo(buf);
|
||||||
|
#endif
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the resolution from the given string and store
|
* Extract the resolution from the given string and store
|
||||||
@@ -612,6 +646,7 @@ static const OptionData _options[] = {
|
|||||||
GETOPT_SHORT_VALUE('c'),
|
GETOPT_SHORT_VALUE('c'),
|
||||||
GETOPT_SHORT_NOVAL('x'),
|
GETOPT_SHORT_NOVAL('x'),
|
||||||
GETOPT_SHORT_VALUE('q'),
|
GETOPT_SHORT_VALUE('q'),
|
||||||
|
GETOPT_SHORT_VALUE('K'),
|
||||||
GETOPT_SHORT_NOVAL('h'),
|
GETOPT_SHORT_NOVAL('h'),
|
||||||
GETOPT_SHORT_VALUE('J'),
|
GETOPT_SHORT_VALUE('J'),
|
||||||
GETOPT_END()
|
GETOPT_END()
|
||||||
@@ -730,7 +765,8 @@ int openttd_main(int argc, char *argv[])
|
|||||||
scanner->generation_seed = InteractiveRandom();
|
scanner->generation_seed = InteractiveRandom();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'q': {
|
case 'q':
|
||||||
|
case 'K': {
|
||||||
DeterminePaths(argv[0]);
|
DeterminePaths(argv[0]);
|
||||||
if (StrEmpty(mgo.opt)) {
|
if (StrEmpty(mgo.opt)) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@@ -742,10 +778,12 @@ int openttd_main(int argc, char *argv[])
|
|||||||
FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, strrchr(mgo.opt, '.'), title, lastof(title));
|
FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, strrchr(mgo.opt, '.'), title, lastof(title));
|
||||||
|
|
||||||
_load_check_data.Clear();
|
_load_check_data.Clear();
|
||||||
|
if (i == 'K') _load_check_data.want_debug_log_data = true;
|
||||||
SaveOrLoadResult res = SaveOrLoad(mgo.opt, SLO_CHECK, DFT_GAME_FILE, SAVE_DIR, false);
|
SaveOrLoadResult res = SaveOrLoad(mgo.opt, SLO_CHECK, DFT_GAME_FILE, SAVE_DIR, false);
|
||||||
if (res != SL_OK || _load_check_data.HasErrors()) {
|
if (res != SL_OK || _load_check_data.HasErrors()) {
|
||||||
fprintf(stderr, "Failed to open savegame\n");
|
fprintf(stderr, "Failed to open savegame\n");
|
||||||
if (_load_check_data.HasErrors()) {
|
if (_load_check_data.HasErrors()) {
|
||||||
|
InitializeLanguagePacks();
|
||||||
char buf[256];
|
char buf[256];
|
||||||
SetDParamStr(0, _load_check_data.error_data);
|
SetDParamStr(0, _load_check_data.error_data);
|
||||||
GetString(buf, _load_check_data.error, lastof(buf));
|
GetString(buf, _load_check_data.error, lastof(buf));
|
||||||
@@ -754,7 +792,11 @@ int openttd_main(int argc, char *argv[])
|
|||||||
goto exit_noshutdown;
|
goto exit_noshutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i == 'q') {
|
||||||
WriteSavegameInfo(title);
|
WriteSavegameInfo(title);
|
||||||
|
} else {
|
||||||
|
WriteSavegameDebugData(title);
|
||||||
|
}
|
||||||
|
|
||||||
goto exit_noshutdown;
|
goto exit_noshutdown;
|
||||||
}
|
}
|
||||||
@@ -1528,7 +1570,12 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
|
|||||||
}
|
}
|
||||||
if (veh_cache[length].cached_max_speed != u->vcache.cached_max_speed || veh_cache[length].cached_cargo_age_period != u->vcache.cached_cargo_age_period ||
|
if (veh_cache[length].cached_max_speed != u->vcache.cached_max_speed || veh_cache[length].cached_cargo_age_period != u->vcache.cached_cargo_age_period ||
|
||||||
veh_cache[length].cached_vis_effect != u->vcache.cached_vis_effect || HasBit(veh_cache[length].cached_veh_flags ^ u->vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT)) {
|
veh_cache[length].cached_vis_effect != u->vcache.cached_vis_effect || HasBit(veh_cache[length].cached_veh_flags ^ u->vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT)) {
|
||||||
CCLOG("vehicle cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
|
CCLOG("vehicle cache mismatch: %c%c%c%c, type %i, vehicle %i, company %i, unit number %i, wagon %i",
|
||||||
|
veh_cache[length].cached_max_speed != u->vcache.cached_max_speed ? 'm' : '-',
|
||||||
|
veh_cache[length].cached_cargo_age_period != u->vcache.cached_cargo_age_period ? 'c' : '-',
|
||||||
|
veh_cache[length].cached_vis_effect != u->vcache.cached_vis_effect ? 'v' : '-',
|
||||||
|
HasBit(veh_cache[length].cached_veh_flags ^ u->vcache.cached_veh_flags, VCF_LAST_VISUAL_EFFECT) ? 'l' : '-',
|
||||||
|
(int)v->type, v->index, (int)v->owner, v->unitnumber, length);
|
||||||
}
|
}
|
||||||
if (u->IsGroundVehicle() && (HasBit(u->GetGroundVehicleFlags(), GVF_GOINGUP_BIT) || HasBit(u->GetGroundVehicleFlags(), GVF_GOINGDOWN_BIT)) && u->GetGroundVehicleCache()->cached_slope_resistance && HasBit(v->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST)) {
|
if (u->IsGroundVehicle() && (HasBit(u->GetGroundVehicleFlags(), GVF_GOINGUP_BIT) || HasBit(u->GetGroundVehicleFlags(), GVF_GOINGDOWN_BIT)) && u->GetGroundVehicleCache()->cached_slope_resistance && HasBit(v->vcache.cached_veh_flags, VCF_GV_ZERO_SLOPE_RESIST)) {
|
||||||
CCLOG("VCF_GV_ZERO_SLOPE_RESIST set incorrectly (2): type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
|
CCLOG("VCF_GV_ZERO_SLOPE_RESIST set incorrectly (2): type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length);
|
||||||
@@ -1642,8 +1689,17 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
|
|||||||
|
|
||||||
if (_order_destination_refcount_map_valid) {
|
if (_order_destination_refcount_map_valid) {
|
||||||
btree::btree_map<uint32, uint32> saved_order_destination_refcount_map = std::move(_order_destination_refcount_map);
|
btree::btree_map<uint32, uint32> saved_order_destination_refcount_map = std::move(_order_destination_refcount_map);
|
||||||
|
for (auto iter = saved_order_destination_refcount_map.begin(); iter != saved_order_destination_refcount_map.end();) {
|
||||||
|
if (iter->second == 0) {
|
||||||
|
iter = saved_order_destination_refcount_map.erase(iter);
|
||||||
|
} else {
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
IntialiseOrderDestinationRefcountMap();
|
IntialiseOrderDestinationRefcountMap();
|
||||||
if (saved_order_destination_refcount_map != _order_destination_refcount_map) CCLOG("Order destination refcount map mismatch");
|
if (saved_order_destination_refcount_map != _order_destination_refcount_map) CCLOG("Order destination refcount map mismatch");
|
||||||
|
} else {
|
||||||
|
CCLOG("Order destination refcount map not valid");
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CCLOG
|
#undef CCLOG
|
||||||
|
@@ -58,6 +58,8 @@ INSTANTIATE_POOL_METHODS(OrderList)
|
|||||||
btree::btree_map<uint32, uint32> _order_destination_refcount_map;
|
btree::btree_map<uint32, uint32> _order_destination_refcount_map;
|
||||||
bool _order_destination_refcount_map_valid = false;
|
bool _order_destination_refcount_map_valid = false;
|
||||||
|
|
||||||
|
CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID sel_ord, const Order &new_order, bool allow_load_by_cargo_type);
|
||||||
|
|
||||||
void IntialiseOrderDestinationRefcountMap()
|
void IntialiseOrderDestinationRefcountMap()
|
||||||
{
|
{
|
||||||
ClearOrderDestinationRefcountMap();
|
ClearOrderDestinationRefcountMap();
|
||||||
@@ -942,7 +944,10 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||||||
VehicleOrderID sel_ord = GB(p1, 20, 8);
|
VehicleOrderID sel_ord = GB(p1, 20, 8);
|
||||||
Order new_order(p2);
|
Order new_order(p2);
|
||||||
|
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
return CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID sel_ord, const Order &new_order, bool allow_load_by_cargo_type) {
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
|
|
||||||
CommandCost ret = CheckOwnership(v->owner);
|
CommandCost ret = CheckOwnership(v->owner);
|
||||||
@@ -972,10 +977,16 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||||||
/* Filter invalid load/unload types. */
|
/* Filter invalid load/unload types. */
|
||||||
switch (new_order.GetLoadType()) {
|
switch (new_order.GetLoadType()) {
|
||||||
case OLF_LOAD_IF_POSSIBLE: case OLFB_FULL_LOAD: case OLF_FULL_LOAD_ANY: case OLFB_NO_LOAD: break;
|
case OLF_LOAD_IF_POSSIBLE: case OLFB_FULL_LOAD: case OLF_FULL_LOAD_ANY: case OLFB_NO_LOAD: break;
|
||||||
|
case OLFB_CARGO_TYPE_LOAD:
|
||||||
|
if (allow_load_by_cargo_type) break;
|
||||||
|
return CMD_ERROR;
|
||||||
default: return CMD_ERROR;
|
default: return CMD_ERROR;
|
||||||
}
|
}
|
||||||
switch (new_order.GetUnloadType()) {
|
switch (new_order.GetUnloadType()) {
|
||||||
case OUF_UNLOAD_IF_POSSIBLE: case OUFB_UNLOAD: case OUFB_TRANSFER: case OUFB_NO_UNLOAD: break;
|
case OUF_UNLOAD_IF_POSSIBLE: case OUFB_UNLOAD: case OUFB_TRANSFER: case OUFB_NO_UNLOAD: break;
|
||||||
|
case OUFB_CARGO_TYPE_UNLOAD:
|
||||||
|
if (allow_load_by_cargo_type) break;
|
||||||
|
return CMD_ERROR;
|
||||||
default: return CMD_ERROR;
|
default: return CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1928,6 +1939,17 @@ static void CheckAdvanceVehicleOrdersAfterClone(Vehicle *v, DoCommandFlag flags)
|
|||||||
DoCommand(v->tile, v->index, skip_to, flags, CMD_SKIP_TO_ORDER);
|
DoCommand(v->tile, v->index, skip_to, flags, CMD_SKIP_TO_ORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ShouldResetOrderIndicesOnOrderCopy(const Vehicle *src, const Vehicle *dst)
|
||||||
|
{
|
||||||
|
const int num_orders = src->GetNumOrders();
|
||||||
|
if (dst->GetNumOrders() != num_orders) return true;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_orders; i++) {
|
||||||
|
if (!src->GetOrder(i)->Equals(*dst->GetOrder(i))) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone/share/copy an order-list of another vehicle.
|
* Clone/share/copy an order-list of another vehicle.
|
||||||
* @param tile unused
|
* @param tile unused
|
||||||
@@ -1999,9 +2021,9 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
/* If the destination vehicle had a OrderList, destroy it.
|
/* If the destination vehicle had a OrderList, destroy it.
|
||||||
* We only reset the order indices, if the new orders are obviously different.
|
* We reset the order indices, if the new orders are different.
|
||||||
* (We mainly do this to keep the order indices valid and in range.) */
|
* (We mainly do this to keep the order indices valid and in range.) */
|
||||||
DeleteVehicleOrders(dst, false, dst->GetNumOrders() != src->GetNumOrders());
|
DeleteVehicleOrders(dst, false, ShouldResetOrderIndicesOnOrderCopy(src, dst));
|
||||||
|
|
||||||
dst->orders.list = src->orders.list;
|
dst->orders.list = src->orders.list;
|
||||||
|
|
||||||
@@ -2086,9 +2108,9 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||||||
Order **order_dst;
|
Order **order_dst;
|
||||||
|
|
||||||
/* If the destination vehicle had an order list, destroy the chain but keep the OrderList.
|
/* If the destination vehicle had an order list, destroy the chain but keep the OrderList.
|
||||||
* We only reset the order indices, if the new orders are obviously different.
|
* We only the order indices, if the new orders are different.
|
||||||
* (We mainly do this to keep the order indices valid and in range.) */
|
* (We mainly do this to keep the order indices valid and in range.) */
|
||||||
DeleteVehicleOrders(dst, true, dst->GetNumOrders() != src->GetNumOrders());
|
DeleteVehicleOrders(dst, true, ShouldResetOrderIndicesOnOrderCopy(src, dst));
|
||||||
|
|
||||||
order_dst = &first;
|
order_dst = &first;
|
||||||
FOR_VEHICLE_ORDERS(src, order) {
|
FOR_VEHICLE_ORDERS(src, order) {
|
||||||
@@ -2856,14 +2878,20 @@ CommandCost CmdMassChangeOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
Order new_order;
|
Order new_order;
|
||||||
new_order.AssignOrder(*order);
|
new_order.AssignOrder(*order);
|
||||||
new_order.SetDestination(to_dest);
|
new_order.SetDestination(to_dest);
|
||||||
|
const bool wait_fixed = new_order.IsWaitFixed();
|
||||||
|
const bool wait_timetabled = wait_fixed && new_order.IsWaitTimetabled();
|
||||||
new_order.SetWaitTimetabled(false);
|
new_order.SetWaitTimetabled(false);
|
||||||
new_order.SetTravelTimetabled(false);
|
new_order.SetTravelTimetabled(false);
|
||||||
if (DoCommand(0, v->index | ((index + 1) << 20), new_order.Pack(), flags, CMD_INSERT_ORDER).Succeeded()) {
|
if (CmdInsertOrderIntl(flags, v, index + 1, new_order, true).Succeeded()) {
|
||||||
DoCommand(0, v->index, index, flags, CMD_DELETE_ORDER);
|
DoCommand(0, v->index, index, flags, CMD_DELETE_ORDER);
|
||||||
|
|
||||||
order = v->orders.list->GetOrderAt(index);
|
order = v->orders.list->GetOrderAt(index);
|
||||||
order->SetRefit(new_order.GetRefitCargo());
|
order->SetRefit(new_order.GetRefitCargo());
|
||||||
order->SetMaxSpeed(new_order.GetMaxSpeed());
|
order->SetMaxSpeed(new_order.GetMaxSpeed());
|
||||||
|
if (wait_fixed) {
|
||||||
|
extern void SetOrderFixedWaitTime(Vehicle *v, VehicleOrderID order_number, uint32 wait_time, bool wait_timetabled);
|
||||||
|
SetOrderFixedWaitTime(v, index, new_order.GetWaitTime(), wait_timetabled);
|
||||||
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "../../openttd.h"
|
#include "../../openttd.h"
|
||||||
#include "../../screenshot.h"
|
#include "../../screenshot.h"
|
||||||
#include "../../debug.h"
|
#include "../../debug.h"
|
||||||
|
#include "../../settings_type.h"
|
||||||
#if defined(WITH_DEMANGLE)
|
#if defined(WITH_DEMANGLE)
|
||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -483,6 +484,8 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c
|
|||||||
|
|
||||||
/* virtual */ int CrashLogWindows::WriteCrashDump(char *filename, const char *filename_last) const
|
/* virtual */ int CrashLogWindows::WriteCrashDump(char *filename, const char *filename_last) const
|
||||||
{
|
{
|
||||||
|
if (_settings_client.gui.developer == 0) return 0;
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
HMODULE dbghelp = LoadLibrary(_T("dbghelp.dll"));
|
HMODULE dbghelp = LoadLibrary(_T("dbghelp.dll"));
|
||||||
if (dbghelp != nullptr) {
|
if (dbghelp != nullptr) {
|
||||||
@@ -624,7 +627,7 @@ static bool _expanded;
|
|||||||
|
|
||||||
static const TCHAR _crash_desc[] =
|
static const TCHAR _crash_desc[] =
|
||||||
_T("A serious fault condition occurred in the game. The game will shut down.\n")
|
_T("A serious fault condition occurred in the game. The game will shut down.\n")
|
||||||
_T("Please send the crash information and the crash.dmp file (if any) to the patchpack developer.\n")
|
_T("Please send the crash information (log files and crash saves, if any) to the patchpack developer.\n")
|
||||||
_T("This will greatly help debugging. The correct place to do this is https://www.tt-forums.net/viewtopic.php?f=33&t=73469")
|
_T("This will greatly help debugging. The correct place to do this is https://www.tt-forums.net/viewtopic.php?f=33&t=73469")
|
||||||
_T(" or https://github.com/JGRennison/OpenTTD-patches\n")
|
_T(" or https://github.com/JGRennison/OpenTTD-patches\n")
|
||||||
_T("The information contained in the report is displayed below.\n")
|
_T("The information contained in the report is displayed below.\n")
|
||||||
@@ -689,7 +692,7 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
|||||||
|
|
||||||
TCHAR *text = AllocaM(TCHAR, len);
|
TCHAR *text = AllocaM(TCHAR, len);
|
||||||
_sntprintf(text, len, _crash_desc, OTTD2FS(CrashLogWindows::current->crashlog_filename));
|
_sntprintf(text, len, _crash_desc, OTTD2FS(CrashLogWindows::current->crashlog_filename));
|
||||||
if (OTTD2FS(CrashLogWindows::current->crashdump_filename)[0] != _T('\0')) {
|
if (_settings_client.gui.developer > 0 && OTTD2FS(CrashLogWindows::current->crashdump_filename)[0] != _T('\0')) {
|
||||||
_tcscat(text, _T("\n"));
|
_tcscat(text, _T("\n"));
|
||||||
_tcscat(text, OTTD2FS(CrashLogWindows::current->crashdump_filename));
|
_tcscat(text, OTTD2FS(CrashLogWindows::current->crashdump_filename));
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
#include "saveload_buffer.h"
|
#include "saveload_buffer.h"
|
||||||
|
#include "../fios.h"
|
||||||
|
|
||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
|
||||||
@@ -37,6 +38,19 @@ static void Load_DBGL()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Check_DBGL()
|
||||||
|
{
|
||||||
|
if (!_load_check_data.want_debug_log_data) {
|
||||||
|
SlSkipBytes(SlGetFieldLength());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t length = SlGetFieldLength();
|
||||||
|
if (length) {
|
||||||
|
_load_check_data.debug_log_data.resize(length);
|
||||||
|
ReadBuffer::GetCurrent()->CopyBytes(reinterpret_cast<byte *>(const_cast<char *>(_load_check_data.debug_log_data.data())), length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern const ChunkHandler _debug_chunk_handlers[] = {
|
extern const ChunkHandler _debug_chunk_handlers[] = {
|
||||||
{ 'DBGL', Save_DBGL, Load_DBGL, nullptr, nullptr, CH_RIFF | CH_LAST},
|
{ 'DBGL', Save_DBGL, Load_DBGL, nullptr, Check_DBGL, CH_RIFF | CH_LAST},
|
||||||
};
|
};
|
||||||
|
@@ -96,6 +96,14 @@ class NIHVehicle : public NIHelper {
|
|||||||
b += seprintf(b, lastof(buffer), " Flags: ");
|
b += seprintf(b, lastof(buffer), " Flags: ");
|
||||||
b = v->DumpVehicleFlags(b, lastof(buffer));
|
b = v->DumpVehicleFlags(b, lastof(buffer));
|
||||||
print(buffer);
|
print(buffer);
|
||||||
|
if (v->IsPrimaryVehicle()) {
|
||||||
|
seprintf(buffer, lastof(buffer), " Order indices: real: %u, implicit: %u, tt: %u",
|
||||||
|
v->cur_real_order_index, v->cur_implicit_order_index, v->cur_timetable_order_index);
|
||||||
|
print(buffer);
|
||||||
|
}
|
||||||
|
seprintf(buffer, lastof(buffer), " V Cache: max speed: %u, cargo age period: %u, vis effect: %u",
|
||||||
|
v->vcache.cached_max_speed, v->vcache.cached_cargo_age_period, v->vcache.cached_vis_effect);
|
||||||
|
print(buffer);
|
||||||
if (v->IsGroundVehicle()) {
|
if (v->IsGroundVehicle()) {
|
||||||
const GroundVehicleCache &gvc = *(v->GetGroundVehicleCache());
|
const GroundVehicleCache &gvc = *(v->GetGroundVehicleCache());
|
||||||
seprintf(buffer, lastof(buffer), " GV Cache: weight: %u, slope res: %u, max TE: %u, axle res: %u",
|
seprintf(buffer, lastof(buffer), " GV Cache: weight: %u, slope res: %u, max TE: %u, axle res: %u",
|
||||||
|
@@ -997,3 +997,8 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
|
|||||||
SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
|
SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetOrderFixedWaitTime(Vehicle *v, VehicleOrderID order_number, uint32 wait_time, bool wait_timetabled) {
|
||||||
|
ChangeTimetable(v, order_number, wait_time, MTF_WAIT_TIME, wait_timetabled, true);
|
||||||
|
ChangeTimetable(v, order_number, 1, MTF_SET_WAIT_FIXED, false, true);
|
||||||
|
}
|
||||||
|
@@ -1079,7 +1079,7 @@ static CallBackFunction PlaceLandBlockInfo()
|
|||||||
|
|
||||||
static CallBackFunction ToolbarHelpClick(Window *w)
|
static CallBackFunction ToolbarHelpClick(Window *w)
|
||||||
{
|
{
|
||||||
PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 13 : 10);
|
PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 14 : 11);
|
||||||
return CBF_NONE;
|
return CBF_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1182,10 +1182,11 @@ static CallBackFunction MenuClickHelp(int index)
|
|||||||
case 6: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break;
|
case 6: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break;
|
||||||
case 7: MenuClickLargeWorldScreenshot(SC_WORLD); break;
|
case 7: MenuClickLargeWorldScreenshot(SC_WORLD); break;
|
||||||
case 8: ShowFramerateWindow(); break;
|
case 8: ShowFramerateWindow(); break;
|
||||||
case 9: ShowAboutWindow(); break;
|
case 9: ShowModifierKeyToggleWindow(); break;
|
||||||
case 10: ShowSpriteAlignerWindow(); break;
|
case 10: ShowAboutWindow(); break;
|
||||||
case 11: ToggleBoundingBoxes(); break;
|
case 11: ShowSpriteAlignerWindow(); break;
|
||||||
case 12: ToggleDirtyBlocks(); break;
|
case 12: ToggleBoundingBoxes(); break;
|
||||||
|
case 13: ToggleDirtyBlocks(); break;
|
||||||
}
|
}
|
||||||
return CBF_NONE;
|
return CBF_NONE;
|
||||||
}
|
}
|
||||||
|
@@ -1355,6 +1355,7 @@ static void NormaliseTrainHead(Train *head)
|
|||||||
/* Tell the 'world' the train changed. */
|
/* Tell the 'world' the train changed. */
|
||||||
head->ConsistChanged(CCF_ARRANGE);
|
head->ConsistChanged(CCF_ARRANGE);
|
||||||
UpdateTrainGroupID(head);
|
UpdateTrainGroupID(head);
|
||||||
|
SetBit(head->flags, VRF_CONSIST_SPEED_REDUCTION);
|
||||||
|
|
||||||
/* Not a front engine, i.e. a free wagon chain. No need to do more. */
|
/* Not a front engine, i.e. a free wagon chain. No need to do more. */
|
||||||
if (!head->IsFrontEngine()) return;
|
if (!head->IsFrontEngine()) return;
|
||||||
|
@@ -499,9 +499,10 @@ void VideoDriver_Allegro::MainLoop()
|
|||||||
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
||||||
|
|
||||||
bool old_ctrl_pressed = _ctrl_pressed;
|
bool old_ctrl_pressed = _ctrl_pressed;
|
||||||
|
bool old_shift_pressed = _shift_pressed;
|
||||||
|
|
||||||
_ctrl_pressed = !!(key_shifts & KB_CTRL_FLAG);
|
_ctrl_pressed = !!(key_shifts & KB_CTRL_FLAG) != _invert_ctrl;
|
||||||
_shift_pressed = !!(key_shifts & KB_SHIFT_FLAG);
|
_shift_pressed = !!(key_shifts & KB_SHIFT_FLAG) != _invert_shift;
|
||||||
|
|
||||||
/* determine which directional keys are down */
|
/* determine which directional keys are down */
|
||||||
_dirkeys =
|
_dirkeys =
|
||||||
@@ -511,6 +512,7 @@ void VideoDriver_Allegro::MainLoop()
|
|||||||
(key[KEY_DOWN] ? 8 : 0);
|
(key[KEY_DOWN] ? 8 : 0);
|
||||||
|
|
||||||
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
||||||
|
if (old_shift_pressed != _shift_pressed) HandleShiftChanged();
|
||||||
|
|
||||||
GameLoop();
|
GameLoop();
|
||||||
|
|
||||||
|
@@ -695,11 +695,13 @@ void QZ_GameLoop()
|
|||||||
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
||||||
|
|
||||||
bool old_ctrl_pressed = _ctrl_pressed;
|
bool old_ctrl_pressed = _ctrl_pressed;
|
||||||
|
bool old_shift_pressed = _shift_pressed;
|
||||||
|
|
||||||
_ctrl_pressed = !!(_current_mods & ( _settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? NSControlKeyMask : NSCommandKeyMask));
|
_ctrl_pressed = !!(_current_mods & ( _settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? NSControlKeyMask : NSCommandKeyMask)) != _invert_ctrl;
|
||||||
_shift_pressed = !!(_current_mods & NSShiftKeyMask);
|
_shift_pressed = !!(_current_mods & NSShiftKeyMask) != _invert_shift;
|
||||||
|
|
||||||
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
||||||
|
if (old_shift_pressed != _shift_pressed) HandleShiftChanged();
|
||||||
|
|
||||||
GameLoop();
|
GameLoop();
|
||||||
|
|
||||||
|
@@ -728,9 +728,10 @@ void VideoDriver_SDL::MainLoop()
|
|||||||
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
||||||
|
|
||||||
bool old_ctrl_pressed = _ctrl_pressed;
|
bool old_ctrl_pressed = _ctrl_pressed;
|
||||||
|
bool old_shift_pressed = _shift_pressed;
|
||||||
|
|
||||||
_ctrl_pressed = !!(mod & KMOD_CTRL);
|
_ctrl_pressed = !!(mod & KMOD_CTRL) != _invert_ctrl;
|
||||||
_shift_pressed = !!(mod & KMOD_SHIFT);
|
_shift_pressed = !!(mod & KMOD_SHIFT) != _invert_shift;
|
||||||
|
|
||||||
/* determine which directional keys are down */
|
/* determine which directional keys are down */
|
||||||
_dirkeys =
|
_dirkeys =
|
||||||
@@ -746,6 +747,7 @@ void VideoDriver_SDL::MainLoop()
|
|||||||
(keys[SDLK_DOWN] ? 8 : 0);
|
(keys[SDLK_DOWN] ? 8 : 0);
|
||||||
#endif
|
#endif
|
||||||
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
||||||
|
if (old_shift_pressed != _shift_pressed) HandleShiftChanged();
|
||||||
|
|
||||||
/* The gameloop is the part that can run asynchronously. The rest
|
/* The gameloop is the part that can run asynchronously. The rest
|
||||||
* except sleeping can't. */
|
* except sleeping can't. */
|
||||||
|
@@ -1243,9 +1243,10 @@ void VideoDriver_Win32::MainLoop()
|
|||||||
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
next_tick = cur_ticks + MILLISECONDS_PER_TICK;
|
||||||
|
|
||||||
bool old_ctrl_pressed = _ctrl_pressed;
|
bool old_ctrl_pressed = _ctrl_pressed;
|
||||||
|
bool old_shift_pressed = _shift_pressed;
|
||||||
|
|
||||||
_ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL)<0;
|
_ctrl_pressed = (_wnd.has_focus && GetAsyncKeyState(VK_CONTROL) < 0) != _invert_ctrl;
|
||||||
_shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT)<0;
|
_shift_pressed = (_wnd.has_focus && GetAsyncKeyState(VK_SHIFT) < 0) != _invert_shift;
|
||||||
|
|
||||||
/* determine which directional keys are down */
|
/* determine which directional keys are down */
|
||||||
if (_wnd.has_focus) {
|
if (_wnd.has_focus) {
|
||||||
@@ -1259,6 +1260,7 @@ void VideoDriver_Win32::MainLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
|
||||||
|
if (old_shift_pressed != _shift_pressed) HandleShiftChanged();
|
||||||
|
|
||||||
/* Flush GDI buffer to ensure we don't conflict with the drawing thread. */
|
/* Flush GDI buffer to ensure we don't conflict with the drawing thread. */
|
||||||
GdiFlush();
|
GdiFlush();
|
||||||
|
@@ -57,4 +57,10 @@ enum TextfileWidgets {
|
|||||||
WID_TF_HSCROLLBAR, ///< Horizontal scrollbar to scroll through the textfile left-to-right.
|
WID_TF_HSCROLLBAR, ///< Horizontal scrollbar to scroll through the textfile left-to-right.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Widgets of the #TextfileWindow class. */
|
||||||
|
enum ModifierKeyToggleWidgets {
|
||||||
|
WID_MKT_SHIFT,
|
||||||
|
WID_MKT_CTRL,
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* WIDGETS_MISC_WIDGET_H */
|
#endif /* WIDGETS_MISC_WIDGET_H */
|
||||||
|
@@ -2743,6 +2743,17 @@ void HandleCtrlChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State of SHIFT key has changed
|
||||||
|
*/
|
||||||
|
void HandleShiftChanged()
|
||||||
|
{
|
||||||
|
Window *w;
|
||||||
|
FOR_ALL_WINDOWS_FROM_FRONT(w) {
|
||||||
|
w->OnShiftStateChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a text string at the cursor position into the edit box widget.
|
* Insert a text string at the cursor position into the edit box widget.
|
||||||
* @param wid Edit box widget.
|
* @param wid Edit box widget.
|
||||||
|
@@ -667,6 +667,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
|
virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the shift key has changed
|
||||||
|
*/
|
||||||
|
virtual void OnShiftStateChange() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A click with the left mouse button has been made on the window.
|
* A click with the left mouse button has been made on the window.
|
||||||
|
@@ -755,6 +755,11 @@ enum WindowClass {
|
|||||||
WC_BUILD_VIRTUAL_TRAIN,
|
WC_BUILD_VIRTUAL_TRAIN,
|
||||||
WC_CREATE_TEMPLATE,
|
WC_CREATE_TEMPLATE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifier key toggle window.
|
||||||
|
*/
|
||||||
|
WC_MODIFIER_KEY_TOGGLE,
|
||||||
|
|
||||||
WC_INVALID = 0xFFFF, ///< Invalid window.
|
WC_INVALID = 0xFFFF, ///< Invalid window.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user