Debug: Allow clicking to highlight group in sprite group dump window

pull/393/head
Jonathan G Rennison 2 years ago
parent 6d877b5e70
commit 564d7e5029

@ -213,7 +213,7 @@ public:
}
virtual void ExtraInfo(uint index, NIExtraInfoOutput &output) const {}
virtual void SpriteDump(uint index, std::function<void(const char *)> print) const {}
virtual void SpriteDump(uint index, DumpSpriteGroupPrinter print) const {}
virtual bool ShowExtraInfoOnly(uint index) const { return false; };
virtual bool ShowSpriteDumpButton(uint index) const { return false; };
@ -318,6 +318,8 @@ struct NewGRFInspectWindow : Window {
uint32 extra_info_flags = 0;
btree::btree_map<int, uint> extra_info_click_flag_toggles;
btree::btree_map<int, const SpriteGroup *> sprite_group_lines;
const SpriteGroup *selected_sprite_group = nullptr;
/**
* Check whether the given variable has a parameter.
@ -521,8 +523,20 @@ 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<NewGRFInspectWindow *>(this)->sprite_group_lines.clear();
if (this->sprite_dump) {
nih->SpriteDump(index, line_handler);
nih->SpriteDump(index, [&](const SpriteGroup *group, const char *buf) {
if (this->log_console) DEBUG(misc, 0, " %s", buf);
int offset = i++;
int scroll_offset = offset - this->vscroll->GetPosition();
if (scroll_offset < 0 || scroll_offset >= this->vscroll->GetCapacity()) return;
const_cast<NewGRFInspectWindow *>(this)->sprite_group_lines[offset] = group;
TextColour colour = (this->selected_sprite_group == group) ? TC_LIGHT_BLUE : TC_BLACK;
::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (scroll_offset * this->resize.step_height), buf, colour);
});
return;
} else {
NewGRFInspectWindow *this_mutable = const_cast<NewGRFInspectWindow *>(this);
@ -711,12 +725,21 @@ struct NewGRFInspectWindow : Window {
break;
case WID_NGRFI_MAINPANEL: {
if (this->sprite_dump) return;
/* Get the line, make sure it's within the boundaries. */
int line = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NGRFI_MAINPANEL, TOP_OFFSET);
if (line == INT_MAX) return;
if (this->sprite_dump) {
const SpriteGroup *group = nullptr;
auto iter = this->sprite_group_lines.find(line);
if (iter != this->sprite_group_lines.end()) group = iter->second;
if (group != nullptr || this->selected_sprite_group != nullptr) {
this->selected_sprite_group = (group == this->selected_sprite_group) ? nullptr : group;
this->SetWidgetDirty(WID_NGRFI_MAINPANEL);
}
return;
}
auto iter = this->extra_info_click_flag_toggles.find(line);
if (iter != this->extra_info_click_flag_toggles.end()) {
this->extra_info_flags ^= iter->second;

@ -1619,7 +1619,7 @@ void AnalyseEngineCallbacks()
}
}
void DumpVehicleSpriteGroup(const Vehicle *v, std::function<void(const char *)> print)
void DumpVehicleSpriteGroup(const Vehicle *v, DumpSpriteGroupPrinter print)
{
const SpriteGroup *root_spritegroup = nullptr;
if (v->IsGroundVehicle()) root_spritegroup = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->GetGroundVehicleCache()->first_engine);

@ -691,12 +691,12 @@ bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
return false;
}
void DumpIndustrySpriteGroup(const IndustrySpec *spec, std::function<void(const char *)> print)
void DumpIndustrySpriteGroup(const IndustrySpec *spec, DumpSpriteGroupPrinter print)
{
DumpSpriteGroup(spec->grf_prop.spritegroup[0], std::move(print));
}
void DumpIndustryTileSpriteGroup(const IndustryTileSpec *spec, std::function<void(const char *)> print)
void DumpIndustryTileSpriteGroup(const IndustryTileSpec *spec, DumpSpriteGroupPrinter print)
{
DumpSpriteGroup(spec->grf_prop.spritegroup[0], std::move(print));
}

@ -617,7 +617,7 @@ void TriggerObjectAnimation(Object *o, ObjectAnimationTrigger trigger, const Obj
}
}
void DumpObjectSpriteGroup(const ObjectSpec *spec, std::function<void(const char *)> print)
void DumpObjectSpriteGroup(const ObjectSpec *spec, DumpSpriteGroupPrinter print)
{
DumpSpriteGroup(spec->grf_prop.spritegroup[0], std::move(print));
}

@ -634,7 +634,7 @@ void StationUpdateRoadStopCachedTriggers(BaseStation *st)
}
}
void DumpRoadStopSpriteGroup(const BaseStation *st, const RoadStopSpec *spec, std::function<void(const char *)> print)
void DumpRoadStopSpriteGroup(const BaseStation *st, const RoadStopSpec *spec, DumpSpriteGroupPrinter print)
{
CargoID ctype = CT_DEFAULT_NA;

@ -607,19 +607,17 @@ const DrawTileSprites *TileLayoutSpriteGroup::ProcessRegisters(uint8 *stage) con
struct SpriteGroupDumper {
private:
char buffer[1024];
std::function<void(const char *)> print_fn;
DumpSpriteGroupPrinter print_fn;
const SpriteGroup *top_default_group = nullptr;
btree::btree_set<const DeterministicSpriteGroup *> seen_dsgs;
void print() { this->print_fn(this->buffer); }
enum SpriteGroupDumperFlags {
SGDF_DEFAULT = 1 << 0,
};
public:
SpriteGroupDumper(std::function<void(const char *)> print) : print_fn(print) {}
SpriteGroupDumper(DumpSpriteGroupPrinter print) : print_fn(print) {}
void DumpSpriteGroup(const SpriteGroup *sg, int padding, uint flags);
};
@ -684,9 +682,13 @@ static const char *GetAdjustOperationName(DeterministicSpriteGroupAdjustOperatio
void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint flags)
{
auto print = [&]() {
this->print_fn(sg, this->buffer);
};
if (sg == nullptr) {
seprintf(this->buffer, lastof(this->buffer), "%*sNULL GROUP", padding, "");
this->print();
print();
return;
}
@ -695,15 +697,15 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
const RealSpriteGroup *rsg = (const RealSpriteGroup*)sg;
seprintf(this->buffer, lastof(this->buffer), "%*sReal (loaded: %u, loading: %u) [%u]",
padding, "", (uint)rsg->loaded.size(), (uint)rsg->loading.size(), sg->nfo_line);
this->print();
print();
for (size_t i = 0; i < rsg->loaded.size(); i++) {
seprintf(this->buffer, lastof(this->buffer), "%*sLoaded %u", padding + 2, "", (uint)i);
this->print();
print();
this->DumpSpriteGroup(rsg->loaded[i], padding + 4, 0);
}
for (size_t i = 0; i < rsg->loading.size(); i++) {
seprintf(this->buffer, lastof(this->buffer), "%*sLoading %u", padding + 2, "", (uint)i);
this->print();
print();
this->DumpSpriteGroup(rsg->loading[i], padding + 4, 0);
}
break;
@ -716,25 +718,25 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
if (dsg == this->top_default_group && !(padding == 4 && (flags & SGDF_DEFAULT))) {
seprintf(this->buffer, lastof(this->buffer), "%*sTOP LEVEL DEFAULT GROUP: Deterministic (%s, %s), [%u]",
padding, "", _sg_scope_names[dsg->var_scope], _sg_size_names[dsg->size], dsg->nfo_line);
this->print();
print();
return;
}
auto res = this->seen_dsgs.insert(dsg);
if (!res.second) {
seprintf(this->buffer, lastof(this->buffer), "%*sGROUP SEEN ABOVE: Deterministic (%s, %s), [%u]",
padding, "", _sg_scope_names[dsg->var_scope], _sg_size_names[dsg->size], dsg->nfo_line);
this->print();
print();
return;
}
seprintf(this->buffer, lastof(this->buffer), "%*sDeterministic (%s, %s), [%u]",
padding, "", _sg_scope_names[dsg->var_scope], _sg_size_names[dsg->size], dsg->nfo_line);
this->print();
print();
padding += 2;
for (const auto &adjust : dsg->adjusts) {
char *p = this->buffer;
if (adjust.operation == DSGA_OP_TERNARY) {
p += seprintf(p, lastof(this->buffer), "%*sTERNARY: true: %X, false: %X", padding, "", adjust.and_mask, adjust.add_val);
this->print();
print();
continue;
}
p += seprintf(p, lastof(this->buffer), "%*svar: %X", padding, "", adjust.variable);
@ -757,23 +759,23 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
case DSGA_TYPE_NONE: break;
}
p += seprintf(p, lastof(this->buffer), ", op: %X (%s)", adjust.operation, GetAdjustOperationName(adjust.operation));
this->print();
print();
if (adjust.variable == 0x7E && adjust.subroutine != nullptr) {
this->DumpSpriteGroup(adjust.subroutine, padding + 5, 0);
}
}
if (dsg->calculated_result) {
seprintf(this->buffer, lastof(this->buffer), "%*scalculated_result", padding, "");
this->print();
print();
} else {
for (const auto &range : dsg->ranges) {
seprintf(this->buffer, lastof(this->buffer), "%*srange: %X -> %X", padding, "", range.low, range.high);
this->print();
print();
this->DumpSpriteGroup(range.group, padding + 2, 0);
}
if (dsg->default_group != nullptr) {
seprintf(this->buffer, lastof(this->buffer), "%*sdefault", padding, "");
this->print();
print();
this->DumpSpriteGroup(dsg->default_group, padding + 2, SGDF_DEFAULT);
}
}
@ -784,7 +786,7 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
seprintf(this->buffer, lastof(this->buffer), "%*sRandom (%s, %s, triggers: %X, count: %X, lowest_randbit: %X, groups: %u) [%u]",
padding, "", _sg_scope_names[rsg->var_scope], rsg->cmp_mode == RSG_CMP_ANY ? "ANY" : "ALL",
rsg->triggers, rsg->count, rsg->lowest_randbit, (uint)rsg->groups.size(), rsg->nfo_line);
this->print();
print();
for (const auto &group : rsg->groups) {
this->DumpSpriteGroup(group, padding + 2, 0);
}
@ -792,17 +794,17 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
}
case SGT_CALLBACK:
seprintf(this->buffer, lastof(this->buffer), "%*sCallback Result: %X", padding, "", ((const CallbackResultSpriteGroup *) sg)->result);
this->print();
print();
break;
case SGT_RESULT:
seprintf(this->buffer, lastof(this->buffer), "%*sSprite Result: SpriteID: %u, num: %u",
padding, "", ((const ResultSpriteGroup *) sg)->sprite, ((const ResultSpriteGroup *) sg)->num_sprites);
this->print();
print();
break;
case SGT_TILELAYOUT: {
const TileLayoutSpriteGroup *tlsg = (const TileLayoutSpriteGroup*)sg;
seprintf(this->buffer, lastof(this->buffer), "%*sTile Layout [%u]", padding, "", sg->nfo_line);
this->print();
print();
padding += 2;
if (tlsg->dts.registers != nullptr) {
const TileLayoutRegisters *registers = tlsg->dts.registers;
@ -812,42 +814,42 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
for (size_t i = 0; i < count; i ++) {
const TileLayoutRegisters *reg = registers + i;
seprintf(this->buffer, lastof(this->buffer), "%*ssection: %X, register flags: %X", padding, "", (uint)i, reg->flags);
this->print();
print();
if (reg->flags & TLF_DODRAW) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_DODRAW reg: %X", padding + 2, "", reg->dodraw);
this->print();
print();
}
if (reg->flags & TLF_SPRITE) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_SPRITE reg: %X", padding + 2, "", reg->sprite);
this->print();
print();
}
if (reg->flags & TLF_PALETTE) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_PALETTE reg: %X", padding + 2, "", reg->palette);
this->print();
print();
}
if (reg->flags & TLF_BB_XY_OFFSET) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_BB_XY_OFFSET reg: %X, %X", padding + 2, "", reg->delta.parent[0], reg->delta.parent[1]);
this->print();
print();
}
if (reg->flags & TLF_BB_Z_OFFSET) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_BB_Z_OFFSET reg: %X", padding + 2, "", reg->delta.parent[2]);
this->print();
print();
}
if (reg->flags & TLF_CHILD_X_OFFSET) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_CHILD_X_OFFSET reg: %X", padding + 2, "", reg->delta.child[0]);
this->print();
print();
}
if (reg->flags & TLF_CHILD_Y_OFFSET) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_CHILD_Y_OFFSET reg: %X", padding + 2, "", reg->delta.child[1]);
this->print();
print();
}
if (reg->flags & TLF_SPRITE_VAR10) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_SPRITE_VAR10 value: %X", padding + 2, "", reg->sprite_var10);
this->print();
print();
}
if (reg->flags & TLF_PALETTE_VAR10) {
seprintf(this->buffer, lastof(this->buffer), "%*sTLF_PALETTE_VAR10 value: %X", padding + 2, "", reg->palette_var10);
this->print();
print();
}
}
}
@ -856,15 +858,15 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
case SGT_INDUSTRY_PRODUCTION: {
const IndustryProductionSpriteGroup *ipsg = (const IndustryProductionSpriteGroup*)sg;
seprintf(this->buffer, lastof(this->buffer), "%*sIndustry Production (version %X) [%u]", padding, "", ipsg->version, ipsg->nfo_line);
this->print();
print();
auto log_io = [&](const char *prefix, int i, int quantity, CargoID cargo) {
if (ipsg->version >= 2) {
seprintf(this->buffer, lastof(this->buffer), "%*s%s %X: reg %X, cargo ID: %X", padding + 2, "", prefix, i, quantity, cargo);
this->print();
print();
} else {
const char *type = (ipsg->version >= 1) ? "reg" : "value";
seprintf(this->buffer, lastof(this->buffer), "%*s%s %X: %s %X", padding + 2, "", prefix, i, type, quantity);
this->print();
print();
}
};
for (int i = 0; i < ipsg->num_input; i++) {
@ -874,13 +876,13 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, int padding, uint
log_io("Add input", i, ipsg->add_output[i], ipsg->cargo_output[i]);
}
seprintf(this->buffer, lastof(this->buffer), "%*sAgain: %s %X", padding + 2, "", (ipsg->version >= 1) ? "reg" : "value", ipsg->again);
this->print();
print();
break;
}
}
}
void DumpSpriteGroup(const SpriteGroup *sg, std::function<void(const char *)> print)
void DumpSpriteGroup(const SpriteGroup *sg, DumpSpriteGroupPrinter print)
{
SpriteGroupDumper dumper(std::move(print));
dumper.DumpSpriteGroup(sg, 0, 0);

@ -569,7 +569,9 @@ struct ResolverObject {
virtual uint32 GetDebugID() const { return 0; }
};
void DumpSpriteGroup(const SpriteGroup *sg, std::function<void(const char *)> print);
using DumpSpriteGroupPrinter = std::function<void(const SpriteGroup *, const char *)>;
void DumpSpriteGroup(const SpriteGroup *sg, DumpSpriteGroupPrinter print);
uint32 EvaluateDeterministicSpriteGroupAdjust(DeterministicSpriteGroupSize size, const DeterministicSpriteGroupAdjust &adjust, ScopeResolver *scope, uint32 last_value, uint32 value);
#endif /* NEWGRF_SPRITEGROUP_H */

@ -397,9 +397,9 @@ class NIHVehicle : public NIHelper {
output.print(buffer);
}
/* virtual */ void SpriteDump(uint index, std::function<void(const char *)> print) const override
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
extern void DumpVehicleSpriteGroup(const Vehicle *v, std::function<void(const char *)> print);
extern void DumpVehicleSpriteGroup(const Vehicle *v, DumpSpriteGroupPrinter print);
DumpVehicleSpriteGroup(Vehicle::Get(index), std::move(print));
}
};
@ -467,7 +467,7 @@ class NIHStation : public NIHelper {
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, extra);
}
/* virtual */ void SpriteDump(uint index, std::function<void(const char *)> print) const override
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
StationResolverObject ro(GetStationSpec(index), Station::GetByTile(index), index, INVALID_RAILTYPE);
DumpSpriteGroup(ro.root_spritegroup, std::move(print));
@ -567,7 +567,7 @@ class NIHHouse : public NIHelper {
}
}
/* virtual */ void SpriteDump(uint index, std::function<void(const char *)> print) const override
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
DumpSpriteGroup(HouseSpec::Get(GetHouseType(index))->grf_prop.spritegroup[0], std::move(print));
}
@ -640,11 +640,11 @@ class NIHIndustryTile : public NIHelper {
}
}
/* virtual */ void SpriteDump(uint index, std::function<void(const char *)> print) const override
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
const IndustryTileSpec *indts = GetIndustryTileSpec(GetIndustryGfx(index));
if (indts) {
extern void DumpIndustryTileSpriteGroup(const IndustryTileSpec *spec, std::function<void(const char *)> print);
extern void DumpIndustryTileSpriteGroup(const IndustryTileSpec *spec, DumpSpriteGroupPrinter print);
DumpIndustryTileSpriteGroup(indts, std::move(print));
}
}
@ -832,11 +832,11 @@ class NIHIndustry : public NIHelper {
}
}
/* virtual */ void SpriteDump(uint index, std::function<void(const char *)> print) const override
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
const Industry *ind = Industry::GetIfValid(index);
if (ind) {
extern void DumpIndustrySpriteGroup(const IndustrySpec *spec, std::function<void(const char *)> print);
extern void DumpIndustrySpriteGroup(const IndustrySpec *spec, DumpSpriteGroupPrinter print);
DumpIndustrySpriteGroup(GetIndustrySpec(ind->type), std::move(print));
}
}
@ -970,9 +970,9 @@ class NIHObject : public NIHelper {
}
}
/* virtual */ void SpriteDump(uint index, std::function<void(const char *)> print) const override
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
extern void DumpObjectSpriteGroup(const ObjectSpec *spec, std::function<void(const char *)> print);
extern void DumpObjectSpriteGroup(const ObjectSpec *spec, DumpSpriteGroupPrinter print);
DumpObjectSpriteGroup(ObjectSpec::GetByTile(index), std::move(print));
}
};
@ -1482,9 +1482,9 @@ class NIHRoadStop : public NIHelper {
}
}
/* virtual */ void SpriteDump(uint index, std::function<void(const char *)> print) const override
/* virtual */ void SpriteDump(uint index, DumpSpriteGroupPrinter print) const override
{
extern void DumpRoadStopSpriteGroup(const BaseStation *st, const RoadStopSpec *spec, std::function<void(const char *)> print);
extern void DumpRoadStopSpriteGroup(const BaseStation *st, const RoadStopSpec *spec, DumpSpriteGroupPrinter print);
DumpRoadStopSpriteGroup(BaseStation::GetByTile(index), GetRoadStopSpec(index), std::move(print));
}
};

Loading…
Cancel
Save