Merge branch 'master' into blueprints

This commit is contained in:
dP
2021-01-27 19:08:02 +03:00
14 changed files with 300 additions and 89 deletions

View File

@@ -13,10 +13,12 @@
#include "../industry.h"
#include "../landscape.h"
#include "../newgrf_railtype.h"
#include "../newgrf_station.h"
#include "../town.h"
#include "../town_kdtree.h"
#include "../tilearea_type.h"
#include "../tilehighlight_type.h"
#include "../tilehighlight_func.h"
#include "../viewport_func.h"
#include "../zoning.h"
#include "../table/track_land.h"
@@ -40,6 +42,16 @@ RoadBits FindRailsToConnect(TileIndex tile);
extern DiagDirection _build_depot_direction; ///< Currently selected depot direction
extern uint32 _realtime_tick;
struct RailStationGUISettings {
Axis orientation; ///< Currently selected rail station orientation
bool newstations; ///< Are custom station definitions available?
StationClassID station_class; ///< Currently selected custom station class (if newstations is \c true )
byte station_type; ///< %Station type within the currently selected custom station class (if newstations is \c true )
byte station_count; ///< Number of custom stations (if newstations is \c true )
};
extern RailStationGUISettings _railstation; ///< Settings of the station builder GUI
namespace citymania {
@@ -115,7 +127,11 @@ ObjectTileHighlight ObjectTileHighlight::make_rail_tunnel_head(DiagDirection ddi
bool ObjectHighlight::operator==(const ObjectHighlight& oh) {
if (this->type != oh.type) return false;
return (this->tile == oh.tile && this->ddir == oh.ddir && this->blueprint == oh.blueprint);
return (this->tile == oh.tile
&& this->end_tile == oh.end_tile
&& this->axis == oh.axis
&& this->ddir == oh.ddir
&& this->blueprint == oh.blueprint);
// switch (this->type) {
// case Type::RAIL_DEPOT: return this->tile == oh.tile && this->ddir == oh.ddir;
// default: return true;
@@ -128,13 +144,21 @@ bool ObjectHighlight::operator!=(const ObjectHighlight& oh) {
}
ObjectHighlight ObjectHighlight::make_depot(TileIndex tile, DiagDirection ddir) {
ObjectHighlight ObjectHighlight::make_rail_depot(TileIndex tile, DiagDirection ddir) {
auto oh = ObjectHighlight{ObjectHighlight::Type::RAIL_DEPOT};
oh.tile = tile;
oh.ddir = ddir;
return oh;
}
ObjectHighlight ObjectHighlight::make_rail_station(TileIndex start_tile, TileIndex end_tile, Axis axis) {
auto oh = ObjectHighlight{ObjectHighlight::Type::RAIL_STATION};
oh.tile = start_tile;
oh.end_tile = end_tile;
oh.axis = axis;
return oh;
}
ObjectHighlight ObjectHighlight::make_blueprint(TileIndex tile, sp<Blueprint> blueprint) {
auto oh = ObjectHighlight{ObjectHighlight::Type::BLUEPRINT};
oh.tile = tile;
@@ -185,6 +209,13 @@ void ObjectHighlight::UpdateTiles() {
}
break;
}
case Type::RAIL_STATION: {
auto ta = OrthogonalTileArea(this->tile, this->end_tile);
TILE_AREA_LOOP(tile, ta) {
this->tiles.insert({tile, ObjectTileHighlight::make_rail_station(this->axis)});
}
break;
}
case Type::BLUEPRINT:
if (this->blueprint && this->tile != INVALID_TILE)
this->tiles = this->blueprint->GetTiles(this->tile);
@@ -533,21 +564,21 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th)
if (_highlight_station_to_join) highlight_station = _highlight_station_to_join;
if (draw_selection) {
auto b = CalcTileBorders(ti->tile, [](TileIndex t) {
auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE;
return IsInsideSelectedRectangle(x, y);
});
const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN};
auto color = pal[(int)_station_building_status];
if (_thd.make_square_red) color = SPR_PALETTE_ZONING_RED;
if (b.first != ZoningBorder::NONE)
th.add_border(b.first, color);
if (IsInsideSelectedRectangle(TileX(ti->tile) * TILE_SIZE, TileY(ti->tile) * TILE_SIZE)) {
th.ground_pal = GetTintBySelectionColour(color);
return;
}
}
// if (draw_selection) {
// auto b = CalcTileBorders(ti->tile, [](TileIndex t) {
// auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE;
// return IsInsideSelectedRectangle(x, y);
// });
// const SpriteID pal[] = {SPR_PALETTE_ZONING_RED, SPR_PALETTE_ZONING_YELLOW, SPR_PALETTE_ZONING_LIGHT_BLUE, SPR_PALETTE_ZONING_GREEN};
// auto color = pal[(int)_station_building_status];
// if (_thd.make_square_red) color = SPR_PALETTE_ZONING_RED;
// if (b.first != ZoningBorder::NONE)
// th.add_border(b.first, color);
// if (IsInsideSelectedRectangle(TileX(ti->tile) * TILE_SIZE, TileY(ti->tile) * TILE_SIZE)) {
// th.ground_pal = GetTintBySelectionColour(color);
// return;
// }
// }
auto coverage_getter = [draw_selection, highlight_station](TileIndex t) {
auto x = TileX(t) * TILE_SIZE, y = TileY(t) * TILE_SIZE;
@@ -835,6 +866,38 @@ DiagDirection AutodetectRailObjectDirection(TileIndex tile, Point pt) {
NOT_REACHED();
}
TileIndex _autodetection_tile = INVALID_TILE;
DiagDirDiff _autodetection_rotation = DIAGDIRDIFF_SAME;
static DiagDirDiff GetAutodetectionRotation() {
auto pt = GetTileBelowCursor();
auto tile = TileVirtXY(pt.x, pt.y);
if (tile != _autodetection_tile) {
_autodetection_tile = tile;
_autodetection_rotation = DIAGDIRDIFF_SAME;
}
return _autodetection_rotation;
}
void RotateAutodetection() {
auto rotation = GetAutodetectionRotation();
if (rotation == DIAGDIRDIFF_90LEFT) rotation = DIAGDIRDIFF_SAME;
else rotation++;
_autodetection_rotation = rotation;
::UpdateTileSelection();
}
void ResetRotateAutodetection() {
_autodetection_tile = INVALID_TILE;
_autodetection_rotation = DIAGDIRDIFF_SAME;
}
DiagDirection AddAutodetectionRotation(DiagDirection ddir) {
return ChangeDiagDir(ddir, GetAutodetectionRotation());
}
HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
_thd.cm_new = ObjectHighlight(ObjectHighlight::Type::NONE);
auto pt = GetTileBelowCursor();
@@ -846,9 +909,20 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
_cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) {
auto dir = _build_depot_direction;
if (pt.x != -1) {
if (dir >= DiagDirection::DIAGDIR_END)
dir = AutodetectRailObjectDirection(tile, pt);
_thd.cm_new = ObjectHighlight::make_depot(tile, dir);
if (dir >= DiagDirection::DIAGDIR_END) {
dir = AddAutodetectionRotation(AutodetectRailObjectDirection(tile, pt));
}
_thd.cm_new = ObjectHighlight::make_rail_depot(tile, dir);
}
new_drawstyle = HT_RECT;
} else if (_thd.outersize.x > 0) { // station
if (_thd.size.x >= (int)TILE_SIZE && _thd.size.y >= (int)TILE_SIZE) {
auto start_tile = TileXY(_thd.pos.x / TILE_SIZE, _thd.pos.y / TILE_SIZE);
auto end_tile = TileXY(
std::min((_thd.pos.x + _thd.size.x) / TILE_SIZE, MapSizeX()) - 1,
std::min((_thd.pos.y + _thd.size.y) / TILE_SIZE, MapSizeY()) - 1
);
_thd.cm_new = ObjectHighlight::make_rail_station(start_tile, end_tile, _railstation.orientation);
}
new_drawstyle = HT_RECT;
}

View File

@@ -95,6 +95,9 @@ void SetIndustryForbiddenTilesHighlight(IndustryType type);
PaletteID GetTreeShadePal(TileIndex tile);
void RotateAutodetection();
void ResetRotateAutodetection();
} // namespace citymania
#endif

View File

@@ -154,15 +154,18 @@ public:
enum class Type {
NONE = 0,
RAIL_DEPOT = 1,
BLUEPRINT = 2,
RAIL_STATION = 2,
BLUEPRINT = 3,
};
protected:
Type type;
TileIndex tile = INVALID_TILE;
TileIndex end_tile = INVALID_TILE;
Axis axis = INVALID_AXIS;
DiagDirection ddir = INVALID_DIAGDIR;
sp<Blueprint> blueprint = nullptr;
protected:
bool tiles_updated = false;
std::multimap<TileIndex, ObjectTileHighlight> tiles;
void UpdateTiles();
@@ -173,7 +176,8 @@ public:
bool operator==(const ObjectHighlight& oh);
bool operator!=(const ObjectHighlight& oh);
static ObjectHighlight make_depot(TileIndex tile, DiagDirection ddir);
static ObjectHighlight make_rail_depot(TileIndex tile, DiagDirection ddir);
static ObjectHighlight make_rail_station(TileIndex start_tile, TileIndex end_tile, Axis axis);
static ObjectHighlight make_blueprint(TileIndex tile, sp<Blueprint> blueprint);
void Draw(const TileInfo *ti);

View File

@@ -35,6 +35,9 @@ bool _fn_mod = false;
bool _remove_mod = false;
bool _estimate_mod = false;
bool _middle_button_down; ///< Is middle mouse button pressed?
bool _middle_button_clicked; ///< Is middle mouse button clicked?
uint32 _effective_actions = 0;
uint32 _first_effective_tick = 0;
std::queue<uint32> _last_actions;

View File

@@ -112,6 +112,10 @@ enum WindowKeyCodes {
WKC_EXCLAIM = 160, ///< ! Exclamation mark
WKC_ASTERISK = 161, ///< * Asterisk
WKC_DOLLAR = 162, ///< $ Dollar sign
CM_WKC_MOUSE_MIDDLE = 0x703, ///< CityMania: special code for middle mouse button
CM_WKC_MOUSE_OTHER_START = 0x704, ///< CityMania: start of the numbered buttons (whatever number driver reports), starts as MOUSE_4 hotkey
CM_WKC_MOUSE_OTHER_END = 0x71f, ///< CityMania: 30 buttons should be enough for any mouse, right? ;)
};
/** A single sprite of a list of animated cursors */

View File

@@ -85,6 +85,35 @@ static const KeycodeNames _keycode_to_name[] = {
{"R_PAREN", WKC_R_PAREN},
{"EXCLAIM", WKC_EXCLAIM},
{"ASTERISK", WKC_ASTERISK},
{"MOUSE_MIDDLE", CM_WKC_MOUSE_MIDDLE},
{"MOUSE_4", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 0)},
{"MOUSE_5", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 1)},
{"MOUSE_6", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 2)},
{"MOUSE_7", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 3)},
{"MOUSE_8", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 4)},
{"MOUSE_9", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 5)},
{"MOUSE_10", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 6)},
{"MOUSE_11", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 7)},
{"MOUSE_12", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 8)},
{"MOUSE_13", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 9)},
{"MOUSE_14", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 10)},
{"MOUSE_15", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 11)},
{"MOUSE_16", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 12)},
{"MOUSE_17", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 13)},
{"MOUSE_18", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 14)},
{"MOUSE_19", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 15)},
{"MOUSE_20", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 16)},
{"MOUSE_21", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 17)},
{"MOUSE_22", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 18)},
{"MOUSE_23", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 19)},
{"MOUSE_24", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 20)},
{"MOUSE_25", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 21)},
{"MOUSE_26", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 22)},
{"MOUSE_27", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 23)},
{"MOUSE_28", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 24)},
{"MOUSE_29", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 25)},
{"MOUSE_30", (WindowKeyCodes)(CM_WKC_MOUSE_OTHER_START + 26)},
};
/**

View File

@@ -203,7 +203,7 @@ void NetworkExecuteLocalCommandQueue()
if (_frame_counter > cp->frame) {
/* If we reach here, it means for whatever reason, we've already executed
* past the command we need to execute. */
error("[net] Trying to execute a packet in the past!");
error("[net] Trying to execute a packet in the past! (frame=%u cmd_frame=%u tile=%u p1=%u p2=%u cmd=%u)", (uint)_frame_counter, (uint)cp->frame, (uint)cp->tile, (uint)cp->p1, (uint)cp->p2, (uint)cp->cmd);
}
/* We can execute this command */

View File

@@ -40,6 +40,7 @@
#include "citymania/cm_blueprint.hpp"
#include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_highlight.hpp"
#include "citymania/cm_station_gui.hpp"
#include "safeguards.h"
@@ -504,30 +505,6 @@ RoadBits FindRailsToConnect(TileIndex tile) {
return passing;
}
/*
* Selects orientation for rail object (depot)
*/
DiagDirection AutodetectRailObjectDirection(TileIndex tile) {
RoadBits bits = FindRailsToConnect(tile);
// FIXME after this point repeats road autodetection
if (HasExactlyOneBit(bits)) return RoadBitsToDiagDir(bits);
if (bits == ROAD_NONE) bits = ROAD_ALL;
RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
frac_bits |= MirrorRoadBits(frac_bits);
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
if (DiagDirToRoadBits(ddir) & bits) {
return ddir;
}
}
NOT_REACHED();
}
/** Rail toolbar management class. */
struct BuildRailToolbarWindow : Window {
RailType railtype; ///< Rail type to build.
@@ -715,6 +692,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_DEPOT:
if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | (HighLightStyle)_build_depot_direction)) {
citymania::ResetRotateAutodetection();
ShowBuildTrainDepotPicker(this);
this->last_user_action = widget;
}
@@ -852,7 +830,8 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_DEPOT:
ddir = _build_depot_direction;
if (ddir == DIAGDIR_NW + 1) {
ddir = AutodetectRailObjectDirection(tile);
assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT);
ddir = _thd.cm.ddir;
}
DoCommandP(tile, _cur_railtype, ddir,
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
@@ -1144,7 +1123,14 @@ static void HandleStationPlacement(TileIndex start, TileIndex end)
ShowSelectStationIfNeeded(cmdcont, ta);
}
struct BuildRailStationWindow : public PickerWindowBase {
/* CityMania code start */
public:
enum class Hotkey : int {
ROTATE,
};
/* CityMania code end */
private:
uint line_height; ///< Height of a single line in the newstation selection matrix (#WID_BRAS_NEWST_LIST widget).
uint coverage_height; ///< Height of the coverage texts.
@@ -1628,8 +1614,40 @@ public:
{
CheckRedrawStationCoverage(this);
}
/* CityMania code start */
EventState OnHotkey(int hotkey) override
{
switch ((BuildRailStationWindow::Hotkey)hotkey) {
/* Indicate to the OnClick that the action comes from a hotkey rather
* then from a click and that the CTRL state should be ignored. */
case BuildRailStationWindow::Hotkey::ROTATE:
this->RaiseWidget(_railstation.orientation + WID_BRAS_PLATFORM_DIR_X);
_railstation.orientation = OtherAxis(_railstation.orientation);
this->LowerWidget(_railstation.orientation + WID_BRAS_PLATFORM_DIR_X);
this->SetDirty();
DeleteWindowById(WC_SELECT_STATION, 0);
return ES_HANDLED;
default:
NOT_REACHED();
}
return ES_NOT_HANDLED;
}
static HotkeyList hotkeys;
/* CityMania code end */
};
/* CityMania code start */
static Hotkey build_station_hotkeys[] = {
Hotkey(CM_WKC_MOUSE_MIDDLE, "rotate", (int)BuildRailStationWindow::Hotkey::ROTATE),
HOTKEY_LIST_END
};
HotkeyList BuildRailStationWindow::hotkeys("cm_build_rail_station", build_station_hotkeys);
/* CityMania code end */
static const NWidgetPart _nested_station_builder_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
@@ -1729,7 +1747,8 @@ static WindowDesc _station_builder_desc(
WDP_AUTO, "build_station_rail", 350, 0,
WC_BUILD_STATION, WC_BUILD_TOOLBAR,
WDF_CONSTRUCTION,
_nested_station_builder_widgets, lengthof(_nested_station_builder_widgets)
_nested_station_builder_widgets, lengthof(_nested_station_builder_widgets),
&BuildRailStationWindow::hotkeys // CityMania addition
);
/** Open station build window */
@@ -1952,7 +1971,15 @@ static void ShowSignalBuilder(Window *parent)
new BuildSignalWindow(&_signal_builder_desc, parent);
}
struct BuildRailDepotWindow : public PickerWindowBase {
/* CityMania code start */
public:
enum class Hotkey : int {
ROTATE,
};
/* CityMania code end */
BuildRailDepotWindow(WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
{
this->InitNested(TRANSPORT_RAIL);
@@ -1999,8 +2026,43 @@ struct BuildRailDepotWindow : public PickerWindowBase {
break;
}
}
/* CityMania code start */
EventState OnHotkey(int hotkey) override
{
switch ((BuildRailDepotWindow::Hotkey)hotkey) {
/* Indicate to the OnClick that the action comes from a hotkey rather
* then from a click and that the CTRL state should be ignored. */
case BuildRailDepotWindow::Hotkey::ROTATE:
if (_build_depot_direction < DIAGDIR_END) {
this->RaiseWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
_build_depot_direction = ChangeDiagDir(_build_depot_direction, DIAGDIRDIFF_90RIGHT);
this->LowerWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
} else {
citymania::RotateAutodetection();
}
this->SetDirty();
return ES_HANDLED;
default:
NOT_REACHED();
}
return ES_NOT_HANDLED;
}
static HotkeyList hotkeys;
/* CityMania code end */
};
/* CityMania code start */
static Hotkey build_depot_hotkeys[] = {
Hotkey(CM_WKC_MOUSE_MIDDLE, "rotate", (int)BuildRailDepotWindow::Hotkey::ROTATE),
HOTKEY_LIST_END
};
HotkeyList BuildRailDepotWindow::hotkeys("cm_build_rail_depot", build_depot_hotkeys);
/* CityMania code end */
/** Nested widget definition of the build rail depot window */
static const NWidgetPart _nested_build_depot_widgets[] = {
NWidget(NWID_HORIZONTAL),
@@ -2042,7 +2104,8 @@ static WindowDesc _build_depot_desc(
WDP_AUTO, nullptr, 0, 0,
WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
WDF_CONSTRUCTION,
_nested_build_depot_widgets, lengthof(_nested_build_depot_widgets)
_nested_build_depot_widgets, lengthof(_nested_build_depot_widgets),
&BuildRailDepotWindow::hotkeys // CityMania addition
);
static void ShowBuildTrainDepotPicker(Window *parent)

View File

@@ -370,7 +370,8 @@ static void QZ_MouseMovedEvent(int x, int y)
}
static void QZ_MouseButtonEvent(int button, BOOL down)
static void
QZ_MouseButtonEvent(int button, BOOL down)
{
switch (button) {
case 0:
@@ -392,6 +393,18 @@ static void QZ_MouseButtonEvent(int button, BOOL down)
}
HandleMouseEvents();
break;
case 2:
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
break;
default: {
int button = CM_WKC_MOUSE_OTHER_START + ev.button.button - 3;
if (!down && button >= CM_WKC_MOUSE_OTHER_START && button < CM_WKC_MOUSE_OTHER_END) {
HandleKeypress(button, 0);
}
break
}
}
}
@@ -501,11 +514,11 @@ static bool QZ_PollEvent()
QZ_MouseButtonEvent(1, NO);
break;
#if 0
// #if 0 CityMania uses this!
/* This is not needed since openttd currently only use two buttons */
case NSOtherMouseDown:
pt = QZ_GetMouseLocation(event);
if (!QZ_MouseIsInsideView(&pt)) {
pt = _cocoa_subdriver->GetMouseLocation(event);
if (!_cocoa_subdriver->MouseIsInsideView(&pt)) {
[ NSApp sendEvent:event ];
break;
}
@@ -515,8 +528,8 @@ static bool QZ_PollEvent()
break;
case NSOtherMouseUp:
pt = QZ_GetMouseLocation(event);
if (!QZ_MouseIsInsideView(&pt)) {
pt = _cocoa_subdriver->GetMouseLocation(event);
if (!_cocoa_subdriver->MouseIsInsideView(&pt)) {
[ NSApp sendEvent:event ];
break;
}
@@ -524,7 +537,7 @@ static bool QZ_PollEvent()
QZ_MouseMovedEvent((int)pt.x, (int)pt.y);
QZ_MouseButtonEvent([ event buttonNumber ], NO);
break;
#endif
// #endif
case NSKeyDown: {
/* Quit, hide and minimize */

View File

@@ -524,7 +524,7 @@ int VideoDriver_SDL::PollEvent()
break;
case SDL_MOUSEBUTTONDOWN:
if (_rightclick_emulate && SDL_GetModState() & KMOD_CTRL) {
if (_rightclick_emulate && (SDL_GetModState() & KMOD_CTRL) && ev.button.button == SDL_BUTTON_LEFT) {
ev.button.button = SDL_BUTTON_RIGHT;
}
@@ -544,6 +544,17 @@ int VideoDriver_SDL::PollEvent()
break;
case SDL_MOUSEBUTTONUP:
if (ev.button.button == SDL_BUTTON_MIDDLE) {
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
break;
} else if (ev.button.button > SDL_BUTTON_RIGHT) {
int button = CM_WKC_MOUSE_OTHER_START + ev.button.button - 4;
if (button >= CM_WKC_MOUSE_OTHER_START && button < CM_WKC_MOUSE_OTHER_END) {
HandleKeypress(button, 0);
}
break;
}
if (_rightclick_emulate) {
_right_button_down = false;
_left_button_down = false;

View File

@@ -27,7 +27,7 @@
#include <condition_variable>
#include <algorithm>
#include "../../citymania/cm_hotkeys.hpp"
#include "../citymania/cm_hotkeys.hpp"
#include "../safeguards.h"
@@ -527,7 +527,7 @@ int VideoDriver_SDL::PollEvent()
break;
case SDL_MOUSEBUTTONDOWN:
if (_rightclick_emulate && SDL_GetModState() & KMOD_CTRL) {
if (_rightclick_emulate && (SDL_GetModState() & KMOD_CTRL) && ev.button.button == SDL_BUTTON_LEFT) {
ev.button.button = SDL_BUTTON_RIGHT;
}
@@ -550,6 +550,17 @@ int VideoDriver_SDL::PollEvent()
break;
case SDL_MOUSEBUTTONUP:
if (ev.button.button == SDL_BUTTON_MIDDLE) {
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
break;
} else if (ev.button.button > SDL_BUTTON_WHEELDOWN) {
int button = CM_WKC_MOUSE_OTHER_START + ev.button.button - 4;
if (button >= CM_WKC_MOUSE_OTHER_START && button < CM_WKC_MOUSE_OTHER_END) {
HandleKeypress(button, 0);
}
break;
}
if (_rightclick_emulate) {
_right_button_down = false;
_left_button_down = false;

View File

@@ -715,6 +715,22 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
HandleMouseEvents();
return 0;
/* CityMania code start */
case WM_MBUTTONUP:
ReleaseCapture();
HandleKeypress(CM_WKC_MOUSE_MIDDLE);
return 0;
case WM_XBUTTONUP: {
ReleaseCapture();
int button = CM_WKC_MOUSE_OTHER_START + ev.button.button - 1;
if (button >= CM_WKC_MOUSE_OTHER_START && button < CM_WKC_MOUSE_OTHER_END) {
HandleKeypress(button, 0);
}
return 0;
}
/* CityMania code end */
case WM_MOUSELEAVE:
UndrawMouseCursor();
_cursor.in_window = false;

View File

@@ -1831,32 +1831,6 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom
_vd.child_screen_sprites_to_draw.clear();
}
/**
* Make sure we don't draw a too big area at a time.
* If we do, the sprite memory will overflow.
*/
static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
{
if ((int64)ScaleByZoom(bottom - top, vp->zoom) * (int64)ScaleByZoom(right - left, vp->zoom) > (int64)(180000 * ZOOM_LVL_BASE * ZOOM_LVL_BASE)) {
if ((bottom - top) > (right - left)) {
int t = (top + bottom) >> 1;
ViewportDrawChk(vp, left, top, right, t);
ViewportDrawChk(vp, left, t, right, bottom);
} else {
int t = (left + right) >> 1;
ViewportDrawChk(vp, left, top, t, bottom);
ViewportDrawChk(vp, t, top, right, bottom);
}
} else {
ViewportDoDraw(vp,
ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(top - vp->top, vp->zoom) + vp->virtual_top,
ScaleByZoom(right - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(bottom - vp->top, vp->zoom) + vp->virtual_top
);
}
}
static inline void ViewportDraw(const ViewPort *vp, int left, int top, int right, int bottom)
{
if (right <= vp->left || bottom <= vp->top) return;
@@ -1871,7 +1845,12 @@ static inline void ViewportDraw(const ViewPort *vp, int left, int top, int right
if (top < vp->top) top = vp->top;
if (bottom > vp->top + vp->height) bottom = vp->top + vp->height;
ViewportDrawChk(vp, left, top, right, bottom);
ViewportDoDraw(vp,
ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(top - vp->top, vp->zoom) + vp->virtual_top,
ScaleByZoom(right - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(bottom - vp->top, vp->zoom) + vp->virtual_top
);
}
/**

View File

@@ -2974,6 +2974,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
case MC_HOVER:
DispatchHoverEvent(w, x - w->left, y - w->top);
break;
}
}