diff --git a/src/lang/english.txt b/src/lang/english.txt index 2b6b0ec88e..eedda24893 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4218,6 +4218,8 @@ STR_NEWGRF_INSPECT_SPRITE_DUMP :{BLACK}S STR_NEWGRF_INSPECT_SPRITE_DUMP_TOOLTIP :{BLACK}Display current sprite chain STR_NEWGRF_INSPECT_SPRITE_DUMP_UNOPT :{BLACK}U STR_NEWGRF_INSPECT_SPRITE_DUMP_UNOPT_TOOLTIP :{BLACK}Display sprite groups without any optimisations applied.{}{}Requires reloading NewGRFs if not previously enabled (misc_debug 10). +STR_NEWGRF_INSPECT_SPRITE_DUMP_GOTO :{BLACK}G +STR_NEWGRF_INSPECT_SPRITE_DUMP_GOTO_TOOLTIP :{BLACK}Scroll to sprite number STR_NEWGRF_INSPECT_SPRITE_DUMP_PANEL_TOOLTIP :{BLACK}Click to highlight sprite group{}Shift+Click to collapse sprite group{}Ctrl+Click to highlight temporary storage register STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT :{STRING1} at {HEX} diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 2f260ac85f..cb2e75bab6 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -323,6 +323,7 @@ struct NewGRFInspectWindow : Window { uint32 extra_info_flags = 0; btree::btree_map extra_info_click_flag_toggles; btree::btree_map sprite_group_lines; + btree::btree_map nfo_line_lines; const SpriteGroup *selected_sprite_group = nullptr; btree::btree_map highlight_tag_lines; uint32 selected_highlight_tag = 0; @@ -394,7 +395,9 @@ struct NewGRFInspectWindow : Window { bool show_sprite_dump_button = GetFeatureHelper(wno)->ShowSpriteDumpButton(::GetFeatureIndex(wno)); this->GetWidget(WID_NGRFI_SPRITE_DUMP_SEL)->SetDisplayedPlane(show_sprite_dump_button ? 0 : SZSP_NONE); this->GetWidget(WID_NGRFI_SPRITE_DUMP_UNOPT_SEL)->SetDisplayedPlane(show_sprite_dump_button ? 0 : SZSP_NONE); + this->GetWidget(WID_NGRFI_SPRITE_DUMP_GOTO_SEL)->SetDisplayedPlane(show_sprite_dump_button ? 0 : SZSP_NONE); this->SetWidgetDisabledState(WID_NGRFI_SPRITE_DUMP_UNOPT, true); + this->SetWidgetDisabledState(WID_NGRFI_SPRITE_DUMP_GOTO, true); this->FinishInitNested(wno); this->vscroll->SetCount(0); @@ -539,6 +542,8 @@ struct NewGRFInspectWindow : Window { ::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); }; const_cast(this)->sprite_group_lines.clear(); + const_cast(this)->highlight_tag_lines.clear(); + const_cast(this)->nfo_line_lines.clear(); if (this->sprite_dump) { SpriteGroupDumper::use_shadows = this->sprite_dump_unopt; bool collapsed = false; @@ -548,6 +553,16 @@ struct NewGRFInspectWindow : Window { nih->SpriteDump(index, [&](const SpriteGroup *group, DumpSpriteGroupPrintOp operation, uint32 highlight_tag, const char *buf) { if (this->log_console && operation == DSGPO_PRINT) DEBUG(misc, 0, " %s", buf); + if (operation == DSGPO_NFO_LINE) { + btree::btree_map &lines = const_cast(this)->nfo_line_lines; + auto iter = lines.lower_bound(highlight_tag); + if (iter != lines.end() && iter->first == (int)highlight_tag) { + /* Already stored, don't insert again */ + } else { + lines.insert(iter, std::make_pair(highlight_tag, std::min(UINT16_MAX, i))); + } + } + if (operation == DSGPO_START && !collapsed && this->collapsed_groups.count(group)) { collapsed = true; collapse_group = group; @@ -869,9 +884,11 @@ struct NewGRFInspectWindow : Window { this->sprite_dump = !this->sprite_dump; this->SetWidgetLoweredState(WID_NGRFI_SPRITE_DUMP, this->sprite_dump); this->SetWidgetDisabledState(WID_NGRFI_SPRITE_DUMP_UNOPT, !this->sprite_dump || !UnOptimisedSpriteDumpOK()); + this->SetWidgetDisabledState(WID_NGRFI_SPRITE_DUMP_GOTO, !this->sprite_dump); this->GetWidget(WID_NGRFI_MAINPANEL)->SetToolTip(this->sprite_dump ? STR_NEWGRF_INSPECT_SPRITE_DUMP_PANEL_TOOLTIP : STR_NULL); this->SetWidgetDirty(WID_NGRFI_SPRITE_DUMP); this->SetWidgetDirty(WID_NGRFI_SPRITE_DUMP_UNOPT); + this->SetWidgetDirty(WID_NGRFI_SPRITE_DUMP_GOTO); this->SetWidgetDirty(WID_NGRFI_MAINPANEL); this->SetWidgetDirty(WID_NGRFI_SCROLLBAR); break; @@ -900,6 +917,12 @@ struct NewGRFInspectWindow : Window { this->SetWidgetDirty(WID_NGRFI_SCROLLBAR); break; } + + case WID_NGRFI_SPRITE_DUMP_GOTO: { + this->current_edit_param = 0; + ShowQueryString(STR_EMPTY, STR_SPRITE_ALIGNER_GOTO_CAPTION, 10, this, CS_NUMERAL, QSF_NONE); + break; + } } } @@ -907,8 +930,17 @@ struct NewGRFInspectWindow : Window { { if (StrEmpty(str)) return; - NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][this->current_edit_param - 0x60] = strtol(str, nullptr, 16); - this->SetDirty(); + if (this->current_edit_param == 0 && this->sprite_dump) { + auto iter = this->nfo_line_lines.find(atoi(str)); + if (iter != this->nfo_line_lines.end()) { + this->vscroll->SetPosition(std::min(iter->second, std::max(0, this->vscroll->GetCount() - this->vscroll->GetCapacity()))); + this->SetWidgetDirty(WID_NGRFI_MAINPANEL); + this->SetWidgetDirty(WID_NGRFI_SCROLLBAR); + } + } else if (this->current_edit_param != 0 && !this->sprite_dump) { + NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][this->current_edit_param - 0x60] = strtol(str, nullptr, 16); + this->SetDirty(); + } } void OnResize() override @@ -951,6 +983,9 @@ static const NWidgetPart _nested_newgrf_inspect_chain_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetDataTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NGRFI_SPRITE_DUMP_GOTO_SEL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_SPRITE_DUMP_GOTO), SetDataTip(STR_NEWGRF_INSPECT_SPRITE_DUMP_GOTO, STR_NEWGRF_INSPECT_SPRITE_DUMP_GOTO_TOOLTIP), + EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NGRFI_SPRITE_DUMP_UNOPT_SEL), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_NGRFI_SPRITE_DUMP_UNOPT), SetDataTip(STR_NEWGRF_INSPECT_SPRITE_DUMP_UNOPT, STR_NEWGRF_INSPECT_SPRITE_DUMP_UNOPT_TOOLTIP), EndContainer(), @@ -985,6 +1020,9 @@ static const NWidgetPart _nested_newgrf_inspect_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetDataTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_PARENT), SetDataTip(STR_NEWGRF_INSPECT_PARENT_BUTTON, STR_NEWGRF_INSPECT_PARENT_TOOLTIP), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NGRFI_SPRITE_DUMP_GOTO_SEL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_SPRITE_DUMP_GOTO), SetDataTip(STR_NEWGRF_INSPECT_SPRITE_DUMP_GOTO, STR_NEWGRF_INSPECT_SPRITE_DUMP_GOTO_TOOLTIP), + EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NGRFI_SPRITE_DUMP_UNOPT_SEL), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_NGRFI_SPRITE_DUMP_UNOPT), SetDataTip(STR_NEWGRF_INSPECT_SPRITE_DUMP_UNOPT, STR_NEWGRF_INSPECT_SPRITE_DUMP_UNOPT_TOOLTIP), EndContainer(), diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 86234218bf..16ee89d507 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -710,6 +710,8 @@ bool SpriteGroupDumper::use_shadows = false; void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint flags) { + if (sg->nfo_line != 0) this->print_fn(sg, DSGPO_NFO_LINE, sg->nfo_line, nullptr); + uint32 highlight_tag = 0; auto print = [&]() { this->print_fn(sg, DSGPO_PRINT, highlight_tag, this->buffer); diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 170bfc17f2..0c738d2366 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -643,6 +643,7 @@ enum DumpSpriteGroupPrintOp { DSGPO_PRINT, DSGPO_START, DSGPO_END, + DSGPO_NFO_LINE, }; using DumpSpriteGroupPrinter = std::function; diff --git a/src/widgets/newgrf_debug_widget.h b/src/widgets/newgrf_debug_widget.h index 4a665fdea1..9607e6da28 100644 --- a/src/widgets/newgrf_debug_widget.h +++ b/src/widgets/newgrf_debug_widget.h @@ -26,6 +26,8 @@ enum NewGRFInspectWidgets { WID_NGRFI_SPRITE_DUMP_SEL, ///< Selection widget for WID_NGRFI_SPRITE_DUMP WID_NGRFI_SPRITE_DUMP_UNOPT, ///< Dump unoptimised sprite group WID_NGRFI_SPRITE_DUMP_UNOPT_SEL, ///< Selection widget for WID_NGRFI_SPRITE_DUMP_UNOPT + WID_NGRFI_SPRITE_DUMP_GOTO, ///< Goto sprite + WID_NGRFI_SPRITE_DUMP_GOTO_SEL, ///< Selection widget for WID_NGRFI_SPRITE_DUMP_GOTO }; /** Widgets of the #SpriteAlignerWindow class. */