/*** Local routines ***/
+/*!
+ * @brief オブジェクトが生存している間、画面表示関数の座標をずらす。
+ *
+ * 引数でずらすX座標オフセット、Y座標オフセットをそれぞれ指定する。
+ * 正方向のオフセットのみ有効。負の値が指定された場合、オフセット位置は 0 とする。
+ * 指定された座標が std::nullopt の場合、現在のオフセットを維持する。
+ *
+ * @param x X座標オフセット
+ * @param y Y座標オフセット
+ */
+TermOffsetSetter::TermOffsetSetter(std::optional<TERM_LEN> x, std::optional<TERM_LEN> y)
+ : term(game_term)
+ , orig_offset_x(game_term != nullptr ? game_term->offset_x : 0)
+ , orig_offset_y(game_term != nullptr ? game_term->offset_y : 0)
+{
+ if (this->term == nullptr) {
+ return;
+ }
+
+ if (x.has_value()) {
+ this->term->offset_x = (x.value() > 0) ? x.value() : 0;
+ }
+ if (y.has_value()) {
+ this->term->offset_y = (y.value() > 0) ? y.value() : 0;
+ }
+}
+
+TermOffsetSetter::~TermOffsetSetter()
+{
+ if (this->term == nullptr) {
+ return;
+ }
+
+ this->term->offset_x = this->orig_offset_x;
+ this->term->offset_y = this->orig_offset_y;
+}
+
+/*!
+ * @brief オブジェクトが生存している間、画面表示関数の座標をずらす。
+ *
+ * 表示に使用する領域の大きさを指定し、その領域が画面中央に表示されるように座標をずらす。
+ * 引数で領域の横幅、縦幅をそれぞれ指定する。
+ * 画面の幅より大きな値が指定された場合はオフセット 0 になる。
+ * 指定された幅が std::nullopt の場合、画面の幅全体を使用する(オフセット 0 になる)。
+ *
+ * @param width 表示に使用する領域の横幅
+ * @param height 表示に使用する領域の縦幅
+ */
+TermCenteredOffsetSetter::TermCenteredOffsetSetter(std::optional<TERM_LEN> width, std::optional<TERM_LEN> height)
+{
+ TERM_LEN term_width, term_height;
+ term_get_size(&term_width, &term_height);
+
+ const auto offset_x = width.has_value() ? (term_width - width.value()) / 2 : 0;
+ const auto offset_y = height.has_value() ? (term_height - height.value()) / 2 : 0;
+ this->tos.emplace(offset_x, offset_y);
+}
+
/*
* Initialize a "term_win" (using the given window size)
*/
* Mentally draw an attr/char at a given location
* Assumes given location and values are valid.
*/
-void term_queue_char(TERM_LEN x, TERM_LEN y, TERM_COLOR a, char c, TERM_COLOR ta, char tc)
+static void term_queue_char_aux(TERM_LEN x, TERM_LEN y, TERM_COLOR a, char c, TERM_COLOR ta, char tc)
{
const auto &scrn = game_term->scr;
}
}
+void term_queue_char(TERM_LEN x, TERM_LEN y, TERM_COLOR a, char c, TERM_COLOR ta, char tc)
+{
+ if (auto res = term_gotoxy(x, y); res != 0) {
+ return;
+ }
+
+ term_queue_char_aux(game_term->scr->cx, game_term->scr->cy, a, c, ta, tc);
+}
+
/*
* Bigtile version of term_queue_char().
* If use_bigtile is FALSE, simply call term_queue_char().
byte a2;
char c2;
+ if (auto res = term_gotoxy(x, y); res != 0) {
+ return;
+ }
+
/* If non bigtile mode, call orginal function */
if (!use_bigtile) {
- term_queue_char(x, y, a, c, ta, tc);
+ term_queue_char_aux(game_term->scr->cx, game_term->scr->cy, a, c, ta, tc);
return;
}
}
/* Display pair of attr/char */
- term_queue_char(x, y, a, c, ta, tc);
- term_queue_char(x + 1, y, a2, c2, 0, 0);
+ term_queue_char_aux(game_term->scr->cx, game_term->scr->cy, a, c, ta, tc);
+ term_queue_char_aux(game_term->scr->cx + 1, game_term->scr->cy, a2, c2, 0, 0);
}
/*
int w = game_term->wid;
int h = game_term->hgt;
+ x += game_term->offset_x;
+ y += game_term->offset_y;
+
/* Verify */
if ((x < 0) || (x >= w)) {
return -1;
*/
errr term_draw(TERM_LEN x, TERM_LEN y, TERM_COLOR a, char c)
{
- int w = game_term->wid;
- int h = game_term->hgt;
-
- if ((x < 0) || (x >= w)) {
- return -1;
- }
- if ((y < 0) || (y >= h)) {
+ if (auto res = term_gotoxy(x, y); res != 0) {
return -1;
}
}
/* Queue it for later */
- term_queue_char(x, y, a, c, 0, 0);
+ term_queue_char_aux(game_term->scr->cx, game_term->scr->cy, a, c, 0, 0);
return 0;
}
}
/* Queue the given character for display */
- term_queue_char(game_term->scr->cx, game_term->scr->cy, a, c, 0, 0);
+ term_queue_char_aux(game_term->scr->cx, game_term->scr->cy, a, c, 0, 0);
/* Advance the cursor */
game_term->scr->cx++;
return -1;
}
+ x = game_term->scr->cx;
+ y = game_term->scr->cy;
+
/* Force legal size */
if (x + n > w) {
n = w - x;
errr term_locate(TERM_LEN *x, TERM_LEN *y)
{
/* Access the cursor */
- (*x) = game_term->scr->cx;
- (*y) = game_term->scr->cy;
+ *x = game_term->scr->cx - game_term->offset_x;
+ *y = game_term->scr->cy - game_term->offset_y;
/* Warn about "useless" cursor */
if (game_term->scr->cu) {
#include "system/angband.h"
#include "system/h-basic.h"
-
#include <memory>
+#include <optional>
#include <stack>
#include <string_view>
#include <vector>
TERM_LEN wid{}; //!< Window Width(max 255)
TERM_LEN hgt{}; //!< Window Height(max 255)
+ TERM_LEN offset_x{};
+ TERM_LEN offset_y{};
+
TERM_LEN y1{}; //!< Minimum modified row
TERM_LEN y2{}; //!< Maximum modified row
term_type &operator=(term_type &&) = default;
};
+class TermOffsetSetter {
+public:
+ TermOffsetSetter(std::optional<TERM_LEN> x, std::optional<TERM_LEN> y);
+ ~TermOffsetSetter();
+ TermOffsetSetter(const TermOffsetSetter &) = delete;
+ TermOffsetSetter &operator=(const TermOffsetSetter &) = delete;
+ TermOffsetSetter(TermOffsetSetter &&) = delete;
+ TermOffsetSetter &operator=(TermOffsetSetter &&) = delete;
+
+private:
+ term_type *term;
+ TERM_LEN orig_offset_x;
+ TERM_LEN orig_offset_y;
+};
+
+class TermCenteredOffsetSetter {
+public:
+ TermCenteredOffsetSetter(std::optional<TERM_LEN> width, std::optional<TERM_LEN> height);
+ ~TermCenteredOffsetSetter() = default;
+ TermCenteredOffsetSetter(const TermCenteredOffsetSetter &) = delete;
+ TermCenteredOffsetSetter &operator=(const TermCenteredOffsetSetter &) = delete;
+ TermCenteredOffsetSetter(TermCenteredOffsetSetter &&) = delete;
+ TermCenteredOffsetSetter &operator=(TermCenteredOffsetSetter &&) = delete;
+
+private:
+ std::optional<TermOffsetSetter> tos;
+};
+
/**** Available Constants ****/
/*