OpenTTD
newgrf_debug_gui.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #include "stdafx.h"
11 #include <stdarg.h>
12 #include "window_gui.h"
13 #include "window_func.h"
14 #include "fileio_func.h"
15 #include "spritecache.h"
16 #include "string_func.h"
17 #include "strings_func.h"
18 #include "textbuf_gui.h"
19 #include "vehicle_gui.h"
20 #include "zoom_func.h"
21 
22 #include "engine_base.h"
23 #include "industry.h"
24 #include "object_base.h"
25 #include "station_base.h"
26 #include "town.h"
27 #include "vehicle_base.h"
28 #include "train.h"
29 #include "roadveh.h"
30 
31 #include "newgrf_airporttiles.h"
32 #include "newgrf_debug.h"
33 #include "newgrf_object.h"
34 #include "newgrf_spritegroup.h"
35 #include "newgrf_station.h"
36 #include "newgrf_town.h"
37 #include "newgrf_railtype.h"
38 #include "newgrf_industries.h"
39 #include "newgrf_industrytiles.h"
40 
42 
43 #include "table/strings.h"
44 
45 #include "safeguards.h"
46 
48 NewGrfDebugSpritePicker _newgrf_debug_sprite_picker = { SPM_NONE, nullptr, 0, std::vector<SpriteID>() };
49 
55 static inline uint GetFeatureIndex(uint window_number)
56 {
57  return GB(window_number, 0, 24);
58 }
59 
67 static inline uint GetInspectWindowNumber(GrfSpecFeature feature, uint index)
68 {
69  assert((index >> 24) == 0);
70  return (feature << 24) | index;
71 }
72 
77 enum NIType {
80 };
81 
83 struct NIProperty {
84  const char *name;
85  ptrdiff_t offset;
86  byte read_size;
87  byte prop;
88  byte type;
89 };
90 
91 
96 struct NICallback {
97  const char *name;
98  ptrdiff_t offset;
99  byte read_size;
100  byte cb_bit;
101  uint16 cb_id;
102 };
104 static const int CBM_NO_BIT = UINT8_MAX;
105 
107 struct NIVariable {
108  const char *name;
109  byte var;
110 };
111 
113 class NIHelper {
114 public:
116  virtual ~NIHelper() {}
117 
123  virtual bool IsInspectable(uint index) const = 0;
124 
130  virtual uint GetParent(uint index) const = 0;
131 
137  virtual const void *GetInstance(uint index) const = 0;
138 
144  virtual const void *GetSpec(uint index) const = 0;
145 
150  virtual void SetStringParameters(uint index) const = 0;
151 
157  virtual uint32 GetGRFID(uint index) const = 0;
158 
167  virtual uint Resolve(uint index, uint var, uint param, bool *avail) const = 0;
168 
173  virtual bool PSAWithParameter() const
174  {
175  return false;
176  }
177 
184  virtual uint GetPSASize(uint index, uint32 grfid) const
185  {
186  return 0;
187  }
188 
195  virtual const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const
196  {
197  return nullptr;
198  }
199 
200 protected:
206  void SetSimpleStringParameters(StringID string, uint32 index) const
207  {
208  SetDParam(0, string);
209  SetDParam(1, index);
210  }
211 
212 
219  void SetObjectAtStringParameters(StringID string, uint32 index, TileIndex tile) const
220  {
221  SetDParam(0, STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT);
222  SetDParam(1, string);
223  SetDParam(2, index);
224  SetDParam(3, tile);
225  }
226 };
227 
228 
230 struct NIFeature {
234  const NIHelper *helper;
235 };
236 
237 /* Load all the NewGRF debug data; externalised as it is just a huge bunch of tables. */
238 #include "table/newgrf_debug_data.h"
239 
245 static inline GrfSpecFeature GetFeatureNum(uint window_number)
246 {
247  return (GrfSpecFeature)GB(window_number, 24, 8);
248 }
249 
255 static inline const NIFeature *GetFeature(uint window_number)
256 {
257  GrfSpecFeature idx = GetFeatureNum(window_number);
258  return idx < GSF_FAKE_END ? _nifeatures[idx] : nullptr;
259 }
260 
267 static inline const NIHelper *GetFeatureHelper(uint window_number)
268 {
269  return GetFeature(window_number)->helper;
270 }
271 
274  static const int LEFT_OFFSET = 5;
275  static const int RIGHT_OFFSET = 5;
276  static const int TOP_OFFSET = 5;
277  static const int BOTTOM_OFFSET = 5;
278 
280  static uint32 var60params[GSF_FAKE_END][0x20];
281 
283  uint32 caller_grfid;
284 
287 
290 
291  Scrollbar *vscroll;
292 
298  static bool HasVariableParameter(uint variable)
299  {
300  return IsInsideBS(variable, 0x60, 0x20);
301  }
302 
307  void SetCallerGRFID(uint32 grfid)
308  {
309  this->caller_grfid = grfid;
310  this->SetDirty();
311  }
312 
316  bool HasChainIndex() const
317  {
318  GrfSpecFeature f = GetFeatureNum(this->window_number);
319  return f == GSF_TRAINS || f == GSF_ROADVEHICLES;
320  }
321 
326  uint GetFeatureIndex() const
327  {
328  uint index = ::GetFeatureIndex(this->window_number);
329  if (this->chain_index > 0) {
330  assert(this->HasChainIndex());
331  const Vehicle *v = Vehicle::Get(index);
332  v = v->Move(this->chain_index);
333  if (v != nullptr) index = v->index;
334  }
335  return index;
336  }
337 
342  {
343  if (this->chain_index == 0) return;
344 
345  assert(this->HasChainIndex());
346 
347  const Vehicle *v = Vehicle::Get(::GetFeatureIndex(this->window_number));
348  v = v->Move(this->chain_index);
349  if (v == nullptr) this->chain_index = 0;
350  }
351 
353  {
354  this->CreateNestedTree();
355  this->vscroll = this->GetScrollbar(WID_NGRFI_SCROLLBAR);
356  this->FinishInitNested(wno);
357 
358  this->vscroll->SetCount(0);
359  this->SetWidgetDisabledState(WID_NGRFI_PARENT, GetFeatureHelper(this->window_number)->GetParent(this->GetFeatureIndex()) == UINT32_MAX);
360 
361  this->OnInvalidateData(0, true);
362  }
363 
364  void SetStringParameters(int widget) const override
365  {
366  if (widget != WID_NGRFI_CAPTION) return;
367 
368  GetFeatureHelper(this->window_number)->SetStringParameters(this->GetFeatureIndex());
369  }
370 
371  void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
372  {
373  switch (widget) {
374  case WID_NGRFI_VEH_CHAIN: {
375  assert(this->HasChainIndex());
376  GrfSpecFeature f = GetFeatureNum(this->window_number);
377  size->height = max(size->height, GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height + 2 + WD_BEVEL_TOP + WD_BEVEL_BOTTOM);
378  break;
379  }
380 
381  case WID_NGRFI_MAINPANEL:
382  resize->height = max(11, FONT_HEIGHT_NORMAL + 1);
383  resize->width = 1;
384 
385  size->height = 5 * resize->height + TOP_OFFSET + BOTTOM_OFFSET;
386  break;
387  }
388  }
389 
396  void WARN_FORMAT(4, 5) DrawString(const Rect &r, int offset, const char *format, ...) const
397  {
398  char buf[1024];
399 
400  va_list va;
401  va_start(va, format);
402  vseprintf(buf, lastof(buf), format, va);
403  va_end(va);
404 
405  offset -= this->vscroll->GetPosition();
406  if (offset < 0 || offset >= this->vscroll->GetCapacity()) return;
407 
408  ::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK);
409  }
410 
411  void DrawWidget(const Rect &r, int widget) const override
412  {
413  switch (widget) {
414  case WID_NGRFI_VEH_CHAIN: {
415  const Vehicle *v = Vehicle::Get(this->GetFeatureIndex());
416  int total_width = 0;
417  int sel_start = 0;
418  int sel_end = 0;
419  for (const Vehicle *u = v->First(); u != nullptr; u = u->Next()) {
420  if (u == v) sel_start = total_width;
421  switch (u->type) {
422  case VEH_TRAIN: total_width += Train ::From(u)->GetDisplayImageWidth(); break;
423  case VEH_ROAD: total_width += RoadVehicle::From(u)->GetDisplayImageWidth(); break;
424  default: NOT_REACHED();
425  }
426  if (u == v) sel_end = total_width;
427  }
428 
429  int width = r.right + 1 - r.left - WD_BEVEL_LEFT - WD_BEVEL_RIGHT;
430  int skip = 0;
431  if (total_width > width) {
432  int sel_center = (sel_start + sel_end) / 2;
433  if (sel_center > width / 2) skip = min(total_width - width, sel_center - width / 2);
434  }
435 
436  GrfSpecFeature f = GetFeatureNum(this->window_number);
437  int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height;
438  int y = (r.top + r.bottom - h) / 2;
439  DrawVehicleImage(v->First(), r.left + WD_BEVEL_LEFT, r.right - WD_BEVEL_RIGHT, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip);
440 
441  /* Highlight the articulated part (this is different to the whole-vehicle highlighting of DrawVehicleImage */
442  if (_current_text_dir == TD_RTL) {
443  DrawFrameRect(r.right - sel_end + skip, y, r.right - sel_start + skip, y + h, COLOUR_WHITE, FR_BORDERONLY);
444  } else {
445  DrawFrameRect(r.left + sel_start - skip, y, r.left + sel_end - skip, y + h, COLOUR_WHITE, FR_BORDERONLY);
446  }
447  break;
448  }
449  }
450 
451  if (widget != WID_NGRFI_MAINPANEL) return;
452 
453  uint index = this->GetFeatureIndex();
454  const NIFeature *nif = GetFeature(this->window_number);
455  const NIHelper *nih = nif->helper;
456  const void *base = nih->GetInstance(index);
457  const void *base_spec = nih->GetSpec(index);
458 
459  uint i = 0;
460  if (nif->variables != nullptr) {
461  this->DrawString(r, i++, "Variables:");
462  for (const NIVariable *niv = nif->variables; niv->name != nullptr; niv++) {
463  bool avail = true;
464  uint param = HasVariableParameter(niv->var) ? NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][niv->var - 0x60] : 0;
465  uint value = nih->Resolve(index, niv->var, param, &avail);
466 
467  if (!avail) continue;
468 
469  if (HasVariableParameter(niv->var)) {
470  this->DrawString(r, i++, " %02x[%02x]: %08x (%s)", niv->var, param, value, niv->name);
471  } else {
472  this->DrawString(r, i++, " %02x: %08x (%s)", niv->var, value, niv->name);
473  }
474  }
475  }
476 
477  uint psa_size = nih->GetPSASize(index, this->caller_grfid);
478  const int32 *psa = nih->GetPSAFirstPosition(index, this->caller_grfid);
479  if (psa_size != 0 && psa != nullptr) {
480  if (nih->PSAWithParameter()) {
481  this->DrawString(r, i++, "Persistent storage [%08X]:", BSWAP32(this->caller_grfid));
482  } else {
483  this->DrawString(r, i++, "Persistent storage:");
484  }
485  assert(psa_size % 4 == 0);
486  for (uint j = 0; j < psa_size; j += 4, psa += 4) {
487  this->DrawString(r, i++, " %i: %i %i %i %i", j, psa[0], psa[1], psa[2], psa[3]);
488  }
489  }
490 
491  if (nif->properties != nullptr) {
492  this->DrawString(r, i++, "Properties:");
493  for (const NIProperty *nip = nif->properties; nip->name != nullptr; nip++) {
494  const void *ptr = (const byte *)base + nip->offset;
495  uint value;
496  switch (nip->read_size) {
497  case 1: value = *(const uint8 *)ptr; break;
498  case 2: value = *(const uint16 *)ptr; break;
499  case 4: value = *(const uint32 *)ptr; break;
500  default: NOT_REACHED();
501  }
502 
503  StringID string;
504  SetDParam(0, value);
505  switch (nip->type) {
506  case NIT_INT:
507  string = STR_JUST_INT;
508  break;
509 
510  case NIT_CARGO:
511  string = value != INVALID_CARGO ? CargoSpec::Get(value)->name : STR_QUANTITY_N_A;
512  break;
513 
514  default:
515  NOT_REACHED();
516  }
517 
518  char buffer[64];
519  GetString(buffer, string, lastof(buffer));
520  this->DrawString(r, i++, " %02x: %s (%s)", nip->prop, buffer, nip->name);
521  }
522  }
523 
524  if (nif->callbacks != nullptr) {
525  this->DrawString(r, i++, "Callbacks:");
526  for (const NICallback *nic = nif->callbacks; nic->name != nullptr; nic++) {
527  if (nic->cb_bit != CBM_NO_BIT) {
528  const void *ptr = (const byte *)base_spec + nic->offset;
529  uint value;
530  switch (nic->read_size) {
531  case 1: value = *(const uint8 *)ptr; break;
532  case 2: value = *(const uint16 *)ptr; break;
533  case 4: value = *(const uint32 *)ptr; break;
534  default: NOT_REACHED();
535  }
536 
537  if (!HasBit(value, nic->cb_bit)) continue;
538  this->DrawString(r, i++, " %03x: %s", nic->cb_id, nic->name);
539  } else {
540  this->DrawString(r, i++, " %03x: %s (unmasked)", nic->cb_id, nic->name);
541  }
542  }
543  }
544 
545  /* Not nice and certainly a hack, but it beats duplicating
546  * this whole function just to count the actual number of
547  * elements. Especially because they need to be redrawn. */
548  const_cast<NewGRFInspectWindow*>(this)->vscroll->SetCount(i);
549  }
550 
551  void OnClick(Point pt, int widget, int click_count) override
552  {
553  switch (widget) {
554  case WID_NGRFI_PARENT: {
555  const NIHelper *nih = GetFeatureHelper(this->window_number);
556  uint index = nih->GetParent(this->GetFeatureIndex());
557  ::ShowNewGRFInspectWindow(GetFeatureNum(index), ::GetFeatureIndex(index), nih->GetGRFID(this->GetFeatureIndex()));
558  break;
559  }
560 
561  case WID_NGRFI_VEH_PREV:
562  if (this->chain_index > 0) {
563  this->chain_index--;
564  this->InvalidateData();
565  }
566  break;
567 
568  case WID_NGRFI_VEH_NEXT:
569  if (this->HasChainIndex()) {
570  uint index = this->GetFeatureIndex();
571  Vehicle *v = Vehicle::Get(index);
572  if (v != nullptr && v->Next() != nullptr) {
573  this->chain_index++;
574  this->InvalidateData();
575  }
576  }
577  break;
578 
579  case WID_NGRFI_MAINPANEL: {
580  /* Does this feature have variables? */
581  const NIFeature *nif = GetFeature(this->window_number);
582  if (nif->variables == nullptr) return;
583 
584  /* Get the line, make sure it's within the boundaries. */
585  int line = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NGRFI_MAINPANEL, TOP_OFFSET);
586  if (line == INT_MAX) return;
587 
588  /* Find the variable related to the line */
589  for (const NIVariable *niv = nif->variables; niv->name != nullptr; niv++, line--) {
590  if (line != 1) continue; // 1 because of the "Variables:" line
591 
592  if (!HasVariableParameter(niv->var)) break;
593 
594  this->current_edit_param = niv->var;
595  ShowQueryString(STR_EMPTY, STR_NEWGRF_INSPECT_QUERY_CAPTION, 9, this, CS_HEXADECIMAL, QSF_NONE);
596  }
597  }
598  }
599  }
600 
601  void OnQueryTextFinished(char *str) override
602  {
603  if (StrEmpty(str)) return;
604 
605  NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][this->current_edit_param - 0x60] = strtol(str, nullptr, 16);
606  this->SetDirty();
607  }
608 
609  void OnResize() override
610  {
611  this->vscroll->SetCapacityFromWidget(this, WID_NGRFI_MAINPANEL, TOP_OFFSET + BOTTOM_OFFSET);
612  }
613 
619  void OnInvalidateData(int data = 0, bool gui_scope = true) override
620  {
621  if (!gui_scope) return;
622  if (this->HasChainIndex()) {
623  this->ValidateChainIndex();
624  this->SetWidgetDisabledState(WID_NGRFI_VEH_PREV, this->chain_index == 0);
625  Vehicle *v = Vehicle::Get(this->GetFeatureIndex());
626  this->SetWidgetDisabledState(WID_NGRFI_VEH_NEXT, v == nullptr || v->Next() == nullptr);
627  }
628  }
629 };
630 
631 /* static */ uint32 NewGRFInspectWindow::var60params[GSF_FAKE_END][0x20] = { {0} }; // Use spec to have 0s in whole array
632 
633 static const NWidgetPart _nested_newgrf_inspect_chain_widgets[] = {
635  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
636  NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetDataTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
637  NWidget(WWT_SHADEBOX, COLOUR_GREY),
638  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
639  NWidget(WWT_STICKYBOX, COLOUR_GREY),
640  EndContainer(),
641  NWidget(WWT_PANEL, COLOUR_GREY),
645  NWidget(WWT_EMPTY, COLOUR_GREY, WID_NGRFI_VEH_CHAIN), SetFill(1, 0), SetResize(1, 0),
646  EndContainer(),
647  EndContainer(),
652  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
653  EndContainer(),
654  EndContainer(),
655 };
656 
657 static const NWidgetPart _nested_newgrf_inspect_widgets[] = {
659  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
660  NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetDataTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
661  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_PARENT), SetDataTip(STR_NEWGRF_INSPECT_PARENT_BUTTON, STR_NEWGRF_INSPECT_PARENT_TOOLTIP),
662  NWidget(WWT_SHADEBOX, COLOUR_GREY),
663  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
664  NWidget(WWT_STICKYBOX, COLOUR_GREY),
665  EndContainer(),
670  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
671  EndContainer(),
672  EndContainer(),
673 };
674 
675 static WindowDesc _newgrf_inspect_chain_desc(
676  WDP_AUTO, "newgrf_inspect_chain", 400, 300,
678  0,
679  _nested_newgrf_inspect_chain_widgets, lengthof(_nested_newgrf_inspect_chain_widgets)
680 );
681 
682 static WindowDesc _newgrf_inspect_desc(
683  WDP_AUTO, "newgrf_inspect", 400, 300,
685  0,
686  _nested_newgrf_inspect_widgets, lengthof(_nested_newgrf_inspect_widgets)
687 );
688 
698 void ShowNewGRFInspectWindow(GrfSpecFeature feature, uint index, const uint32 grfid)
699 {
700  if (!IsNewGRFInspectable(feature, index)) return;
701 
702  WindowNumber wno = GetInspectWindowNumber(feature, index);
703  WindowDesc *desc = (feature == GSF_TRAINS || feature == GSF_ROADVEHICLES) ? &_newgrf_inspect_chain_desc : &_newgrf_inspect_desc;
704  NewGRFInspectWindow *w = AllocateWindowDescFront<NewGRFInspectWindow>(desc, wno, true);
705  w->SetCallerGRFID(grfid);
706 }
707 
717 {
718  if (feature == GSF_INVALID) return;
719 
720  WindowNumber wno = GetInspectWindowNumber(feature, index);
722 }
723 
732 void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
733 {
734  if (feature == GSF_INVALID) return;
735 
736  WindowNumber wno = GetInspectWindowNumber(feature, index);
738 
739  /* Reinitialise the land information window to remove the "debug" sprite if needed.
740  * Note: Since we might be called from a command here, it is important to not execute
741  * the invalidation immediately. The landinfo window tests commands itself. */
743 }
744 
754 bool IsNewGRFInspectable(GrfSpecFeature feature, uint index)
755 {
756  const NIFeature *nif = GetFeature(GetInspectWindowNumber(feature, index));
757  if (nif == nullptr) return false;
758  return nif->helper->IsInspectable(index);
759 }
760 
767 {
768  switch (GetTileType(tile)) {
769  default: return GSF_INVALID;
770  case MP_RAILWAY: return GSF_RAILTYPES;
771  case MP_ROAD: return IsLevelCrossing(tile) ? GSF_RAILTYPES : GSF_INVALID;
772  case MP_HOUSE: return GSF_HOUSES;
773  case MP_INDUSTRY: return GSF_INDUSTRYTILES;
774  case MP_OBJECT: return GSF_OBJECTS;
775 
776  case MP_STATION:
777  switch (GetStationType(tile)) {
778  case STATION_RAIL: return GSF_STATIONS;
779  case STATION_AIRPORT: return GSF_AIRPORTTILES;
780  default: return GSF_INVALID;
781  }
782  }
783 }
784 
791 {
792  switch (type) {
793  case VEH_TRAIN: return GSF_TRAINS;
794  case VEH_ROAD: return GSF_ROADVEHICLES;
795  case VEH_SHIP: return GSF_SHIPS;
796  case VEH_AIRCRAFT: return GSF_AIRCRAFT;
797  default: return GSF_INVALID;
798  }
799 }
800 
801 
802 
803 /**** Sprite Aligner ****/
804 
808 
810  Scrollbar *vscroll;
812 
814  {
815  this->CreateNestedTree();
816  this->vscroll = this->GetScrollbar(WID_SA_SCROLLBAR);
817  this->FinishInitNested(wno);
818 
819  /* Oh yes, we assume there is at least one normal sprite! */
820  while (GetSpriteType(this->current_sprite) != ST_NORMAL) this->current_sprite++;
821  }
822 
823  void SetStringParameters(int widget) const override
824  {
825  const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL);
826  switch (widget) {
827  case WID_SA_CAPTION:
828  SetDParam(0, this->current_sprite);
829  SetDParamStr(1, FioGetFilename(GetOriginFileSlot(this->current_sprite)));
830  break;
831 
832  case WID_SA_OFFSETS_ABS:
833  SetDParam(0, spr->x_offs);
834  SetDParam(1, spr->y_offs);
835  break;
836 
837  case WID_SA_OFFSETS_REL: {
838  /* Relative offset is new absolute offset - starting absolute offset.
839  * Show 0, 0 as the relative offsets if entry is not in the map (meaning they have not been changed yet).
840  */
841  const auto key_offs_pair = this->offs_start_map.Find(this->current_sprite);
842  if (key_offs_pair != this->offs_start_map.end()) {
843  SetDParam(0, spr->x_offs - key_offs_pair->second.first);
844  SetDParam(1, spr->y_offs - key_offs_pair->second.second);
845  } else {
846  SetDParam(0, 0);
847  SetDParam(1, 0);
848  }
849  break;
850  }
851 
852  default:
853  break;
854  }
855  }
856 
857  void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
858  {
859  if (widget != WID_SA_LIST) return;
860 
861  resize->height = max(11, FONT_HEIGHT_NORMAL + 1);
862  resize->width = 1;
863 
864  /* Resize to about 200 pixels (for the preview) */
865  size->height = (1 + 200 / resize->height) * resize->height;
866  }
867 
868  void DrawWidget(const Rect &r, int widget) const override
869  {
870  switch (widget) {
871  case WID_SA_SPRITE: {
872  /* Center the sprite ourselves */
873  const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL);
874  int width = r.right - r.left + 1 - WD_BEVEL_LEFT - WD_BEVEL_RIGHT;
875  int height = r.bottom - r.top + 1 - WD_BEVEL_TOP - WD_BEVEL_BOTTOM;
876  int x = -UnScaleGUI(spr->x_offs) + (width - UnScaleGUI(spr->width) ) / 2;
877  int y = -UnScaleGUI(spr->y_offs) + (height - UnScaleGUI(spr->height)) / 2;
878 
879  DrawPixelInfo new_dpi;
880  if (!FillDrawPixelInfo(&new_dpi, r.left + WD_BEVEL_LEFT, r.top + WD_BEVEL_TOP, width, height)) break;
881  DrawPixelInfo *old_dpi = _cur_dpi;
882  _cur_dpi = &new_dpi;
883 
884  DrawSprite(this->current_sprite, PAL_NONE, x, y, nullptr, ZOOM_LVL_GUI);
885 
886  _cur_dpi = old_dpi;
887 
888  break;
889  }
890 
891  case WID_SA_LIST: {
892  const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget);
893  int step_size = nwid->resize_y;
894 
895  std::vector<SpriteID> &list = _newgrf_debug_sprite_picker.sprites;
896  int max = min<int>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)list.size());
897 
898  int y = r.top + WD_FRAMERECT_TOP;
899  for (int i = this->vscroll->GetPosition(); i < max; i++) {
900  SetDParam(0, list[i]);
901  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
902  y += step_size;
903  }
904  break;
905  }
906  }
907  }
908 
909  void OnClick(Point pt, int widget, int click_count) override
910  {
911  switch (widget) {
912  case WID_SA_PREVIOUS:
913  do {
914  this->current_sprite = (this->current_sprite == 0 ? GetMaxSpriteID() : this->current_sprite) - 1;
915  } while (GetSpriteType(this->current_sprite) != ST_NORMAL);
916  this->SetDirty();
917  break;
918 
919  case WID_SA_GOTO:
920  ShowQueryString(STR_EMPTY, STR_SPRITE_ALIGNER_GOTO_CAPTION, 7, this, CS_NUMERAL, QSF_NONE);
921  break;
922 
923  case WID_SA_NEXT:
924  do {
925  this->current_sprite = (this->current_sprite + 1) % GetMaxSpriteID();
926  } while (GetSpriteType(this->current_sprite) != ST_NORMAL);
927  this->SetDirty();
928  break;
929 
930  case WID_SA_PICKER:
931  this->LowerWidget(WID_SA_PICKER);
932  _newgrf_debug_sprite_picker.mode = SPM_WAIT_CLICK;
933  this->SetDirty();
934  break;
935 
936  case WID_SA_LIST: {
937  const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget);
938  int step_size = nwid->resize_y;
939 
940  uint i = this->vscroll->GetPosition() + (pt.y - nwid->pos_y) / step_size;
941  if (i < _newgrf_debug_sprite_picker.sprites.size()) {
942  SpriteID spr = _newgrf_debug_sprite_picker.sprites[i];
943  if (GetSpriteType(spr) == ST_NORMAL) this->current_sprite = spr;
944  }
945  this->SetDirty();
946  break;
947  }
948 
949  case WID_SA_UP:
950  case WID_SA_DOWN:
951  case WID_SA_LEFT:
952  case WID_SA_RIGHT: {
953  /*
954  * Yes... this is a hack.
955  *
956  * No... I don't think it is useful to make this less of a hack.
957  *
958  * If you want to align sprites, you just need the number. Generally
959  * the sprite caches are big enough to not remove the sprite from the
960  * cache. If that's not the case, just let the NewGRF developer
961  * increase the cache size instead of storing thousands of offsets
962  * for the incredibly small chance that it's actually going to be
963  * used by someone and the sprite cache isn't big enough for that
964  * particular NewGRF developer.
965  */
966  Sprite *spr = const_cast<Sprite *>(GetSprite(this->current_sprite, ST_NORMAL));
967 
968  /* Remember the original offsets of the current sprite, if not already in mapping. */
969  if (!(this->offs_start_map.Contains(this->current_sprite))) {
970  this->offs_start_map.Insert(this->current_sprite, XyOffs(spr->x_offs, spr->y_offs));
971  }
972  switch (widget) {
973  /* Move eight units at a time if ctrl is pressed. */
974  case WID_SA_UP: spr->y_offs -= _ctrl_pressed ? 8 : 1; break;
975  case WID_SA_DOWN: spr->y_offs += _ctrl_pressed ? 8 : 1; break;
976  case WID_SA_LEFT: spr->x_offs -= _ctrl_pressed ? 8 : 1; break;
977  case WID_SA_RIGHT: spr->x_offs += _ctrl_pressed ? 8 : 1; break;
978  }
979  /* Of course, we need to redraw the sprite, but where is it used?
980  * Everywhere is a safe bet. */
982  break;
983  }
984 
985  case WID_SA_RESET_REL:
986  /* Reset the starting offsets for the current sprite. */
987  this->offs_start_map.Erase(this->current_sprite);
988  this->SetDirty();
989  break;
990  }
991  }
992 
993  void OnQueryTextFinished(char *str) override
994  {
995  if (StrEmpty(str)) return;
996 
997  this->current_sprite = atoi(str);
998  if (this->current_sprite >= GetMaxSpriteID()) this->current_sprite = 0;
999  while (GetSpriteType(this->current_sprite) != ST_NORMAL) {
1000  this->current_sprite = (this->current_sprite + 1) % GetMaxSpriteID();
1001  }
1002  this->SetDirty();
1003  }
1004 
1010  void OnInvalidateData(int data = 0, bool gui_scope = true) override
1011  {
1012  if (!gui_scope) return;
1013  if (data == 1) {
1014  /* Sprite picker finished */
1015  this->RaiseWidget(WID_SA_PICKER);
1016  this->vscroll->SetCount((uint)_newgrf_debug_sprite_picker.sprites.size());
1017  }
1018  }
1019 
1020  void OnResize() override
1021  {
1022  this->vscroll->SetCapacityFromWidget(this, WID_SA_LIST);
1023  }
1024 };
1025 
1026 static const NWidgetPart _nested_sprite_aligner_widgets[] = {
1028  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1029  NWidget(WWT_CAPTION, COLOUR_GREY, WID_SA_CAPTION), SetDataTip(STR_SPRITE_ALIGNER_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1030  NWidget(WWT_SHADEBOX, COLOUR_GREY),
1031  NWidget(WWT_STICKYBOX, COLOUR_GREY),
1032  EndContainer(),
1033  NWidget(WWT_PANEL, COLOUR_GREY),
1034  NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 10),
1035  NWidget(NWID_VERTICAL), SetPIP(10, 5, 10),
1037  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_PREVIOUS), SetDataTip(STR_SPRITE_ALIGNER_PREVIOUS_BUTTON, STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP), SetFill(1, 0),
1038  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_GOTO), SetDataTip(STR_SPRITE_ALIGNER_GOTO_BUTTON, STR_SPRITE_ALIGNER_GOTO_TOOLTIP), SetFill(1, 0),
1039  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_NEXT), SetDataTip(STR_SPRITE_ALIGNER_NEXT_BUTTON, STR_SPRITE_ALIGNER_NEXT_TOOLTIP), SetFill(1, 0),
1040  EndContainer(),
1041  NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
1042  NWidget(NWID_SPACER), SetFill(1, 1),
1043  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_UP), SetDataTip(SPR_ARROW_UP, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
1044  NWidget(NWID_SPACER), SetFill(1, 1),
1045  EndContainer(),
1046  NWidget(NWID_HORIZONTAL_LTR), SetPIP(10, 5, 10),
1048  NWidget(NWID_SPACER), SetFill(1, 1),
1049  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_LEFT), SetDataTip(SPR_ARROW_LEFT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
1050  NWidget(NWID_SPACER), SetFill(1, 1),
1051  EndContainer(),
1052  NWidget(WWT_PANEL, COLOUR_DARK_BLUE, WID_SA_SPRITE), SetDataTip(STR_NULL, STR_SPRITE_ALIGNER_SPRITE_TOOLTIP),
1053  EndContainer(),
1055  NWidget(NWID_SPACER), SetFill(1, 1),
1056  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_RIGHT), SetDataTip(SPR_ARROW_RIGHT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
1057  NWidget(NWID_SPACER), SetFill(1, 1),
1058  EndContainer(),
1059  EndContainer(),
1060  NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
1061  NWidget(NWID_SPACER), SetFill(1, 1),
1062  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
1063  NWidget(NWID_SPACER), SetFill(1, 1),
1064  EndContainer(),
1065  NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_ABS), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_ABS, STR_NULL), SetFill(1, 0), SetPadding(0, 10, 0, 10),
1066  NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_REL), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_REL, STR_NULL), SetFill(1, 0), SetPadding(0, 10, 0, 10),
1067  NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
1068  NWidget(NWID_SPACER), SetFill(1, 1),
1069  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_RESET_REL), SetDataTip(STR_SPRITE_ALIGNER_RESET_BUTTON, STR_SPRITE_ALIGNER_RESET_TOOLTIP), SetFill(0, 0),
1070  NWidget(NWID_SPACER), SetFill(1, 1),
1071  EndContainer(),
1072  EndContainer(),
1073  NWidget(NWID_VERTICAL), SetPIP(10, 5, 10),
1074  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_PICKER), SetDataTip(STR_SPRITE_ALIGNER_PICKER_BUTTON, STR_SPRITE_ALIGNER_PICKER_TOOLTIP), SetFill(1, 0),
1076  NWidget(WWT_MATRIX, COLOUR_GREY, WID_SA_LIST), SetResize(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetFill(1, 1), SetScrollbar(WID_SA_SCROLLBAR),
1077  NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SA_SCROLLBAR),
1078  EndContainer(),
1079  EndContainer(),
1080  EndContainer(),
1081  EndContainer(),
1082 };
1083 
1084 static WindowDesc _sprite_aligner_desc(
1085  WDP_AUTO, "sprite_aligner", 400, 300,
1087  0,
1088  _nested_sprite_aligner_widgets, lengthof(_nested_sprite_aligner_widgets)
1089 );
1090 
1095 {
1096  AllocateWindowDescFront<SpriteAlignerWindow>(&_sprite_aligner_desc, 0);
1097 }
Move the sprite to the left.
Functions related to OTTD&#39;s strings.
static TileType GetTileType(TileIndex tile)
Get the tiletype of a given tile.
Definition: tile_map.h:96
Road vehicle states.
Empty widget, place holder to reserve space in widget array.
Definition: widget_type.h:46
Functions/types related to NewGRF debugging.
Normal push-button (no toggle button) with image caption.
Definition: widget_type.h:103
int GetDisplayImageWidth(Point *offset=nullptr) const
Get the width of a road vehicle image in the GUI.
Definition: roadveh_cmd.cpp:90
The caption bar of course.
NewGRF handling of rail types.
byte current_edit_param
The currently edited parameter, to update the right one.
Display for vehicle chain.
Data about how and where to blit pixels.
Definition: gfx_type.h:154
uint GetOriginFileSlot(SpriteID sprite)
Get the (FIOS) file slot of a given sprite.
Skip to the previous sprite.
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:928
Reset relative sprite offset.
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
virtual uint GetParent(uint index) const =0
Get the parent "window_number" of a given instance.
Scrollbar for sprite list.
static int UnScaleGUI(int value)
Short-hand to apply GUI zoom level.
Definition: zoom_func.h:66
byte cb_bit
The bit that needs to be set for this callback to be enabled.
High level window description.
Definition: window_gui.h:166
Part of an industry.
Definition: tile_type.h:49
SmallMap< SpriteID, XyOffs > offs_start_map
Mapping of starting offsets for the sprites which have been aligned in the sprite aligner window...
NIType
The type of a property to show.
Train vehicle type.
Definition: vehicle_type.h:24
virtual bool IsInspectable(uint index) const =0
Is the item with the given index inspectable?
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:291
ptrdiff_t offset
Offset of the variable in the class.
Width of left bevel border.
Definition: window_gui.h:54
void DrawVehicleImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip)
Draws an image of a vehicle chain.
Centered label.
Definition: widget_type.h:55
Scrollbar data structure.
Definition: widget_type.h:587
Functions for NewGRF industries.
Only hexadecimal characters.
Definition: string_type.h:31
const char * name
The human readable name of the callback.
Base for the train class.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
Offset at top to draw the frame rectangular area.
Definition: window_gui.h:62
NewGrfDebugSpritePicker _newgrf_debug_sprite_picker
The sprite picker.
Horizontal container.
Definition: widget_type.h:73
Arrow to the right or in case of RTL to the left.
Definition: widget_type.h:36
Arrow to the left or in case of RTL to the right.
Definition: widget_type.h:35
std::vector< SpriteID > sprites
Sprites found.
Definition: newgrf_debug.h:30
A tile with road (or tram tracks)
Definition: tile_type.h:43
void SetSimpleStringParameters(StringID string, uint32 index) const
Helper to make setting the strings easier.
Data structure describing a sprite.
Definition: spritecache.h:16
void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition: misc_gui.cpp:1119
Ship vehicle type.
Definition: vehicle_type.h:26
Representation on the NewGRF variables.
Move the sprite up.
virtual uint32 GetGRFID(uint index) const =0
Get the GRFID of the file that includes this item.
std::vector< Pair >::const_iterator Find(const T &key) const
Finds given key in this map.
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
Go to previous vehicle in chain.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
Safer implementation of vsnprintf; same as vsnprintf except:
Definition: string.cpp:60
byte read_size
Number of bytes (i.e. byte, word, dword etc)
uint16 cb_id
The number of the callback.
Implementation of simple mapping class.
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:66
Move the sprite down.
Vehicle data structure.
Definition: vehicle_base.h:210
Panel widget containing the actual data.
VehicleCellSize GetVehicleImageCellSize(VehicleType type, EngineImageType image_type)
Get the GUI cell size for a vehicle image.
Definition: depot_gui.cpp:158
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
uint height
Vehicle cell height.
Definition: vehicle_gui.h:78
static uint GetInspectWindowNumber(GrfSpecFeature feature, uint index)
Get the window number for the inspect window given a feature and index.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
Width of right bevel border.
Definition: window_gui.h:55
Close box (at top-left of a window)
Definition: widget_type.h:67
The actual sprite.
The property is a cargo.
Caption of the window.
Functions for Standard In/Out file operations.
void SetStringParameters(int widget) const override
Initialize string parameters for a widget.
const char * FioGetFilename(uint8 slot)
Get the filename associated with a slot.
Definition: fileio.cpp:76
const NIHelper * helper
The class container all helper functions.
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:48
A railway.
Definition: tile_type.h:42
Stuff related to the text buffer GUI.
Contains objects such as transmitters and owned land.
Definition: tile_type.h:51
byte read_size
The number of bytes (i.e. byte, word, dword etc) to read.
const NICallback * callbacks
The callbacks associated with this feature.
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
Definition: vehicle_type.h:55
Vehicle drawn in depot.
Definition: vehicle_type.h:87
static bool IsLevelCrossing(TileIndex t)
Return whether a tile is a level crossing.
Definition: road_map.h:84
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:24
Inspect the parent.
uint32 caller_grfid
GRFID of the caller of this window, 0 if it has no caller.
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
An invalid spec feature.
Definition: newgrf.h:92
Functions related to the vehicle&#39;s GUIs.
void OnQueryTextFinished(char *str) override
The query window opened from this window has closed.
static StationType GetStationType(TileIndex t)
Get the station type of this tile.
Definition: station_map.h:44
static const NIHelper * GetFeatureHelper(uint window_number)
Get the NIHelper related to the window number.
StringID name
Name of this type of cargo.
Definition: cargotype.h:70
SpriteType GetSpriteType(SpriteID sprite)
Get the sprite type of a given sprite.
Functions, definitions and such used only by the GUI.
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Definition: gfx.cpp:1481
Types related to the newgrf debug widgets.
Representation of the available callbacks with information on when they actually apply.
static bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
Definition: math_func.hpp:248
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition: widget.cpp:175
void SetCount(int num)
Sets the number of elements in the list.
Definition: widget_type.h:668
Force the alignment, i.e. don&#39;t swap for RTL languages.
Definition: gfx_func.h:106
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:908
Sprite aligner (debug); Window numbers:
Definition: window_type.h:668
Functions related to NewGRF objects.
Data structure for an opened window.
Definition: window_gui.h:276
Vehicle * Move(int n)
Get the vehicle at offset n of this vehicle chain.
Definition: vehicle_base.h:621
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:35
virtual uint Resolve(uint index, uint var, uint param, bool *avail) const =0
Resolve (action2) variable for a given index.
static NWidgetPart SetMatrixDataTip(uint8 cols, uint8 rows, StringID tip)
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
Definition: widget_type.h:1030
void InvalidateNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Invalidate the inspect window for a given feature and index.
static NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
Widget part function for setting additional space around a widget.
Definition: widget_type.h:1044
Vehicle drawn in vehicle details, refit window, ...
Definition: vehicle_type.h:88
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
Base for all objects.
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:279
Window used for inspecting NewGRFs.
static const NIFeature *const _nifeatures[]
Table with all NIFeatures.
GrfSpecFeature
Definition: newgrf.h:66
Functions related to low-level strings.
Only numeric ones.
Definition: string_type.h:28
Action 2 handling.
Invisible widget that takes some space.
Definition: widget_type.h:77
static GrfSpecFeature GetFeatureNum(uint window_number)
Get the feature number related to the window number.
int16 y_offs
Number of pixels to shift the sprite downwards.
Definition: spritecache.h:20
virtual ~NIHelper()
Silence a warning.
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX) ...
Definition: widget_type.h:63
int GetScrolledRowFromWidget(int clickpos, const Window *const w, int widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition: widget.cpp:1957
virtual void SetStringParameters(uint index) const =0
Set the string parameters to write the right data for a STRINGn.
Simple pair of data.
Skip to the next sprite.
NewGRF inspect (debug); Window numbers:
Definition: window_type.h:662
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:176
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1012
uint GetFeatureIndex() const
Get the feature index.
bool Contains(const T &key) const
Tests whether a key is assigned in this map.
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:945
SmallPair< int16, int16 > XyOffs
Pair for x and y offsets of the sprite before alignment. First value contains the x offset...
Definition of base types and functions in a cross-platform compatible way.
Height of bottom bevel border.
Definition: window_gui.h:57
void SetCallerGRFID(uint32 grfid)
Set the GRFID of the item opening this window.
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
A number of safeguards to prevent using unsafe methods.
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:102
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
Simple depressed panel.
Definition: widget_type.h:48
void SetObjectAtStringParameters(StringID string, uint32 index, TileIndex tile) const
Helper to make setting the strings easier for objects at a specific tile.
End of the fake features.
Definition: newgrf.h:90
virtual const int32 * GetPSAFirstPosition(uint index, uint32 grfid) const
Gets the first position of the array containing the persistent storage.
The property is a simple integer.
The sprite offsets (relative).
static NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx=-1)
Widget part function for starting a new &#39;real&#39; widget.
Definition: widget_type.h:1112
Baseclass for nested widgets.
Definition: widget_type.h:124
uint chain_index
For ground vehicles: Index in vehicle chain.
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition: gfx.cpp:498
bool Insert(const T &key, const U &data)
Adds new item to this map.
void ShowNewGRFInspectWindow(GrfSpecFeature feature, uint index, const uint32 grfid)
Show the inspect window for a given feature and index.
GrfSpecFeature GetGrfSpecFeature(TileIndex tile)
Get the GrfSpecFeature associated with the tile.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
Move the sprite to the right.
uint resize_y
Vertical resize step (0 means not resizable).
Definition: widget_type.h:165
Grid of rows and columns.
Definition: widget_type.h:57
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
Go to a given sprite.
Land info window; Window numbers:
Definition: window_type.h:143
virtual const void * GetInstance(uint index) const =0
Get the instance given an index.
Go to next vehicle in chain.
virtual const void * GetSpec(uint index) const =0
Get (NewGRF) specs given an index.
const NIProperty * properties
The properties associated with this feature.
Functions to cache sprites in memory.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:592
NewGRF handling of industry tiles.
void OnResize() override
Called after the window got resized.
const char * name
A (human readable) name for the property.
Draw border only, no background.
Definition: window_gui.h:28
NewGRF handling of airport tiles.
const NIVariable * variables
The variables associated with this feature.
virtual uint GetPSASize(uint index, uint32 grfid) const
Allows to know the size of the persistent storage.
void Erase(Pair *pair)
Removes given pair from this map.
uint16 height
Height of the sprite.
Definition: spritecache.h:17
The most basic (normal) sprite.
Definition: gfx_type.h:297
void OnQueryTextFinished(char *str) override
The query window opened from this window has closed.
static const int CBM_NO_BIT
Mask to show no bit needs to be enabled for the callback.
void OnResize() override
Called after the window got resized.
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:38
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1162
uint GetMaxSpriteID()
Get a reasonable (upper bound) estimate of the maximum SpriteID used in OpenTTD; there will be no spr...
uint16 width
Width of the sprite.
Definition: spritecache.h:18
int GetDisplayImageWidth(Point *offset=nullptr) const
Get the width of a train vehicle image in the GUI.
Definition: train_cmd.cpp:432
Base class for engines.
SpriteID current_sprite
The currently shown sprite.
Header file for NewGRF stations.
static bool HasVariableParameter(uint variable)
Check whether the given variable has a parameter.
Height of top bevel border.
Definition: window_gui.h:56
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:59
Base class for all vehicles.
static uint GetFeatureIndex(uint window_number)
Get the feature index related to the window number.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
virtual bool PSAWithParameter() const
Used to decide if the PSA needs a parameter or not.
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:57
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:117
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition: vehicle_base.h:579
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:48
Helper class to wrap some functionality/queries in.
ptrdiff_t offset
Offset of the variable in the class.
Window used for aligning sprites.
Vertical container.
Definition: widget_type.h:75
static NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME, WWT_INSET, or WWT_PANEL).
Definition: widget_type.h:997
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Functions related to zooming.
static const byte INVALID_CARGO
Constant representing invalid cargo.
Definition: cargotype.h:52
A tile of a station.
Definition: tile_type.h:46
int16 x_offs
Number of pixels to shift the sprite to the right.
Definition: spritecache.h:19
bool HasChainIndex() const
Check whether this feature has chain index, i.e.
Sprite picker.
Coordinates of a point in 2D.
Normal push-button (no toggle button) with arrow caption.
Definition: widget_type.h:104
uint16 GetCapacity() const
Gets the number of visible elements of the scrollbar.
Definition: widget_type.h:620
Spritepicker of SpriteAligner.
Definition: newgrf_debug.h:26
Base of all industries.
Aircraft vehicle type.
Definition: vehicle_type.h:27
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:61
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:64
Representation of the data from a NewGRF property.
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:981
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
void ValidateChainIndex()
Ensure that this->chain_index is in range.
Base of the town class.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Data &#39;tables&#39; for NewGRF debugging.
Functions to handle the town part of NewGRF towns.
int32 WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:705
void SetCapacityFromWidget(Window *w, int widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget. ...
Definition: widget.cpp:1971
Specification of a rectangle with absolute coordinates of all edges.
Vertical scrollbar.
Definition: widget_type.h:82
A house by a town.
Definition: tile_type.h:44
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
Text is written right-to-left by default.
Definition: strings_type.h:24
Right align the text (must be a single bit).
Definition: gfx_func.h:96
Queried sprite list.
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Window functions not directly related to making/drawing windows.
Find a place automatically.
Definition: window_gui.h:154
byte prop
The number of the property.
Base classes/functions for stations.
The sprite offsets (absolute).
Container for all information for a given feature.
static const NIFeature * GetFeature(uint window_number)
Get the NIFeature related to the window number.
static NWidgetPart SetScrollbar(int index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1093
static uint32 var60params[GSF_FAKE_END][0x20]
The value for the variable 60 parameters.
Dimensions (a width and height) of a rectangle in 2D.
Value of the NCB_EQUALSIZE flag.
Definition: widget_type.h:427
Offset at left to draw the frame rectangular area.
Definition: window_gui.h:60
NewGrfDebugSpritePickerMode mode
Current state.
Definition: newgrf_debug.h:27
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:62
Road vehicle type.
Definition: vehicle_type.h:25
Horizontal container that doesn&#39;t change the order of the widgets for RTL languages.
Definition: widget_type.h:74
bool IsNewGRFInspectable(GrfSpecFeature feature, uint index)
Can we inspect the data given a certain feature and index.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:835
void ShowSpriteAlignerWindow()
Show the window for aligning sprites.
static NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
Widget part function for setting a pre/inter/post spaces.
Definition: widget_type.h:1074
int pos_y
Vertical position of top-left corner of the widget in the window.
Definition: widget_type.h:176
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3316
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition: gfx.cpp:1462
(Toggle) Button with text
Definition: widget_type.h:53
uint16 GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:629
void SetStringParameters(int widget) const override
Initialize string parameters for a widget.
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:199