summaryrefslogtreecommitdiff
path: root/src/newgrf_debug_gui.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-04-25 16:27:30 +0000
committerrubidium <rubidium@openttd.org>2010-04-25 16:27:30 +0000
commitc72e2dde603fe9ba0d57d2e6f259f32398b75a15 (patch)
treea4245990af5d20004a918d8b0131bd3a96e88613 /src/newgrf_debug_gui.cpp
parent4868fb988ff7373ac0b436511464434a310273fd (diff)
downloadopenttd-c72e2dde603fe9ba0d57d2e6f259f32398b75a15.tar.xz
(svn r19723) -Add: a simple sprite alignment helper. It does not store the new offsets anywhere so as soon as the sprite is reloaded the offsets are gone (use a bigger sprite cache if this happens). Also anything that reloads NewGRFs (new games, loading games or (re)applying NewGRFs) clears the sprite cache and as such resets the offsets.
Diffstat (limited to 'src/newgrf_debug_gui.cpp')
-rw-r--r--src/newgrf_debug_gui.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp
index f40a11e54..637c5042d 100644
--- a/src/newgrf_debug_gui.cpp
+++ b/src/newgrf_debug_gui.cpp
@@ -13,7 +13,9 @@
#include <stdarg.h>
#include "window_gui.h"
#include "window_func.h"
+#include "fileio_func.h"
#include "gfx_func.h"
+#include "spritecache.h"
#include "string_func.h"
#include "strings_func.h"
#include "textbuf_gui.h"
@@ -528,3 +530,201 @@ GrfSpecFeature GetGrfSpecFeature(VehicleType type)
default: return GSF_INVALID;
}
}
+
+
+
+/**** Sprite Aligner ****/
+
+/** Widgets we want (some) influence over. */
+enum SpriteAlignerWidgets {
+ SAW_CAPTION, ///< Caption of the window
+ SAW_PREVIOUS, ///< Skip to the previous sprite
+ SAW_GOTO, ///< Go to a given sprite
+ SAW_NEXT, ///< Skip to the next sprite
+ SAW_UP, ///< Move the sprite up
+ SAW_LEFT, ///< Move the sprite to the left
+ SAW_RIGHT, ///< Move the sprite to the right
+ SAW_DOWN, ///< Move the sprite down
+ SAW_SPRITE, ///< The actual sprite
+ SAW_OFFSETS, ///< The sprite offsets
+};
+
+/** Window used for aligning sprites. */
+struct SpriteAlignerWindow : Window {
+ SpriteID current_sprite; ///< The currently shown sprite
+
+ SpriteAlignerWindow(const WindowDesc *desc, WindowNumber wno) : Window()
+ {
+ this->InitNested(desc, wno);
+
+ /* Oh yes, we assume there is at least one normal sprite! */
+ while (GetSpriteType(this->current_sprite) != ST_NORMAL) this->current_sprite++;
+ }
+
+ virtual void SetStringParameters(int widget) const
+ {
+ switch (widget) {
+ case SAW_CAPTION:
+ SetDParam(0, this->current_sprite);
+ SetDParamStr(1, FioGetFilename(GetOriginFileSlot(this->current_sprite)));
+ break;
+
+ case SAW_OFFSETS: {
+ const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL);
+ SetDParam(0, spr->x_offs);
+ SetDParam(1, spr->y_offs);
+ } break;
+
+ default:
+ break;
+ }
+ }
+
+ virtual void DrawWidget(const Rect &r, int widget) const
+ {
+ if (widget != SAW_SPRITE) return;
+
+ /* Center the sprite ourselves */
+ const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL);
+ int width = r.right - r.left + 1;
+ int height = r.bottom - r.top + 1;
+ int x = r.left - spr->x_offs + (width - spr->width) / 2;
+ int y = r.top - spr->y_offs + (height - spr->height) / 2;
+
+ /* And draw only the part within the sprite area */
+ SubSprite subspr = {
+ spr->x_offs + (spr->width - width) / 2 + 1,
+ spr->y_offs + (spr->height - height) / 2 + 1,
+ spr->x_offs + (spr->width + width) / 2 - 1,
+ spr->y_offs + (spr->height + height) / 2 - 1,
+ };
+
+ DrawSprite(this->current_sprite, PAL_NONE, x, y, &subspr);
+ }
+
+ virtual void OnPaint()
+ {
+ this->DrawWidgets();
+ }
+
+ virtual void OnClick(Point pt, int widget, int click_count)
+ {
+ switch (widget) {
+ case SAW_PREVIOUS:
+ do {
+ this->current_sprite = (this->current_sprite == 0 ? GetMaxSpriteID() : this->current_sprite) - 1;
+ } while (GetSpriteType(this->current_sprite) != ST_NORMAL);
+ this->SetDirty();
+ break;
+
+ case SAW_GOTO:
+ ShowQueryString(STR_EMPTY, STR_SPRITE_ALIGNER_GOTO_CAPTION, 7, 150, this, CS_NUMERAL, QSF_NONE);
+ break;
+
+ case SAW_NEXT:
+ do {
+ this->current_sprite = (this->current_sprite + 1) % GetMaxSpriteID();
+ } while (GetSpriteType(this->current_sprite) != ST_NORMAL);
+ this->SetDirty();
+ break;
+
+ case SAW_UP:
+ case SAW_DOWN:
+ case SAW_LEFT:
+ case SAW_RIGHT: {
+ /*
+ * Yes... this is a hack.
+ *
+ * No... I don't think it is useful to make this less of a hack.
+ *
+ * If you want to align sprites, you just need the number. Generally
+ * the sprite caches are big enough to not remove the sprite from the
+ * cache. If that's not the case, just let the NewGRF developer
+ * increase the cache size instead of storing thousands of offsets
+ * for the incredibly small chance that it's actually going to be
+ * used by someone and the sprite cache isn't big enough for that
+ * particular NewGRF developer.
+ */
+ Sprite *spr = const_cast<Sprite *>(GetSprite(this->current_sprite, ST_NORMAL));
+ switch (widget) {
+ case SAW_UP: spr->y_offs--; break;
+ case SAW_DOWN: spr->y_offs++; break;
+ case SAW_LEFT: spr->x_offs--; break;
+ case SAW_RIGHT: spr->x_offs++; break;
+ }
+ /* Ofcourse, we need to redraw the sprite, but where is it used?
+ * Everywhere is a safe bet. */
+ MarkWholeScreenDirty();
+ } break;
+ }
+ }
+
+ virtual void OnQueryTextFinished(char *str)
+ {
+ if (StrEmpty(str)) return;
+
+ this->current_sprite = atoi(str);
+ if (this->current_sprite >= GetMaxSpriteID()) this->current_sprite = 0;
+ while (GetSpriteType(this->current_sprite) != ST_NORMAL) {
+ this->current_sprite = (this->current_sprite + 1) % GetMaxSpriteID();
+ }
+ this->SetDirty();
+ }
+};
+
+static const NWidgetPart _nested_sprite_aligner_widgets[] = {
+ NWidget(NWID_HORIZONTAL),
+ NWidget(WWT_CLOSEBOX, COLOUR_GREY),
+ NWidget(WWT_CAPTION, COLOUR_GREY, SAW_CAPTION), SetDataTip(STR_SPRITE_ALIGNER_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
+ NWidget(WWT_SHADEBOX, COLOUR_GREY),
+ NWidget(WWT_STICKYBOX, COLOUR_GREY),
+ EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_GREY),
+ NWidget(NWID_VERTICAL), SetPIP(10, 5, 10),
+ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 5, 10),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SAW_PREVIOUS), SetDataTip(STR_SPRITE_ALIGNER_PREVIOUS_BUTTON, STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP), SetFill(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SAW_GOTO), SetDataTip(STR_SPRITE_ALIGNER_GOTO_BUTTON, STR_SPRITE_ALIGNER_GOTO_TOOLTIP), SetFill(1, 0),
+ NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SAW_NEXT), SetDataTip(STR_SPRITE_ALIGNER_NEXT_BUTTON, STR_SPRITE_ALIGNER_NEXT_TOOLTIP), SetFill(1, 0),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, SAW_UP), SetDataTip(SPR_ARROW_UP, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL_LTR), SetPIP(10, 5, 10),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, SAW_LEFT), SetDataTip(SPR_ARROW_LEFT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ EndContainer(),
+ NWidget(WWT_PANEL, COLOUR_DARK_BLUE, SAW_SPRITE), SetDataTip(STR_NULL, STR_SPRITE_ALIGNER_SPRITE_TOOLTIP), SetMinimalSize(200, 200),
+ EndContainer(),
+ NWidget(NWID_VERTICAL),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, SAW_RIGHT), SetDataTip(SPR_ARROW_RIGHT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ EndContainer(),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, SAW_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0),
+ NWidget(NWID_SPACER), SetFill(1, 1),
+ EndContainer(),
+ NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
+ NWidget(WWT_LABEL, COLOUR_GREY, SAW_OFFSETS), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS, STR_NULL), SetFill(1, 0),
+ EndContainer(),
+ EndContainer(),
+ EndContainer(),
+};
+
+static const WindowDesc _sprite_aligner_desc(
+ WDP_AUTO, 400, 300,
+ WC_SPRITE_ALIGNER, WC_NONE,
+ WDF_UNCLICK_BUTTONS,
+ _nested_sprite_aligner_widgets, lengthof(_nested_sprite_aligner_widgets)
+);
+
+void ShowSpriteAlignerWindow()
+{
+ AllocateWindowDescFront<SpriteAlignerWindow>(&_sprite_aligner_desc, 0);
+}