OSDN Git Service

[Feature] screen_save()/screen_load()で多重に画面を保存する #891
authorHabu <habu1010+github@gmail.com>
Sat, 24 Apr 2021 15:13:50 +0000 (00:13 +0900)
committerHabu <habu1010+github@gmail.com>
Mon, 26 Apr 2021 13:58:28 +0000 (22:58 +0900)
従来はscreen_save()/screen_load()で保存できる画面は1画面のみだったが、
複数の画面遷移を行き来したい場合に1画面のみでは不便なため、
多重に画面を保存できるようにする。

src/term/screen-processor.cpp
src/term/screen-processor.h
src/term/z-term.cpp
src/term/z-term.h

index 2c15e19..fc1ba68 100644 (file)
@@ -31,10 +31,11 @@ void flush(void) { inkey_xtra = TRUE; }
 void screen_save()
 {
     msg_print(NULL);
-    if (screen_depth++ == 0)
-        term_save();
+
+    term_save();
 
     current_world_ptr->character_icky_depth++;
+    screen_depth++;
 }
 
 /*
@@ -42,13 +43,26 @@ void screen_save()
  *
  * This function must match exactly one call to "screen_save()".
  */
-void screen_load()
+void screen_load(SCREEN_LOAD_OPT opt)
 {
     msg_print(NULL);
-    if (--screen_depth == 0)
-        term_load();
 
-    current_world_ptr->character_icky_depth--;
+    switch (opt) {
+    case SCREEN_LOAD_OPT::ONE:
+        term_load(false);
+        current_world_ptr->character_icky_depth--;
+        screen_depth--;
+        break;
+
+    case SCREEN_LOAD_OPT::ALL:
+        term_load(true);
+        current_world_ptr->character_icky_depth -= static_cast<byte>(screen_depth);
+        screen_depth = 0;
+        break;
+
+    default:
+        break;
+    }
 }
 
 /*
index 79ae0e9..2abeec4 100644 (file)
@@ -2,10 +2,16 @@
 
 #include "system/angband.h"
 
+/** 画面情報保存スタックからの読み出しオプション */
+enum class SCREEN_LOAD_OPT {
+    ONE, //!< スタックの先頭のデータを1つ読み出す
+    ALL, //!< スタックからすべてのデータを読み出す(画面は最後に読み出したデータになる)
+};
+
 void move_cursor(int row, int col);
 void flush(void);
 void screen_save();
-void screen_load();
+void screen_load(SCREEN_LOAD_OPT opt = SCREEN_LOAD_OPT::ONE);
 void c_put_str(TERM_COLOR attr, concptr str, TERM_LEN row, TERM_LEN col);
 void put_str(concptr str, TERM_LEN row, TERM_LEN col);
 void c_prt(TERM_COLOR attr, concptr str, TERM_LEN row, TERM_LEN col);
index e74c1e8..9d9e37e 100644 (file)
@@ -1854,14 +1854,12 @@ errr term_save(void)
     TERM_LEN w = Term->wid;
     TERM_LEN h = Term->hgt;
 
-    /* Create */
-    if (!Term->mem) {
-        /* Allocate window */
-        Term->mem = term_win::create(w, h);
-    }
+    /* Push stack */
+    Term->mem_stack.push(term_win::create(w, h));
 
     /* Grab */
-    term_win_copy(Term->mem, Term->scr, w, h);
+    term_win_copy(Term->mem_stack.top(), Term->scr, w, h);
+
     return 0;
 }
 
@@ -1870,19 +1868,25 @@ errr term_save(void)
  *
  * Every "term_save()" should match exactly one "term_load()"
  */
-errr term_load(void)
+errr term_load(bool load_all)
 {
     TERM_LEN w = Term->wid;
     TERM_LEN h = Term->hgt;
 
-    /* Create */
-    if (!Term->mem) {
-        /* Allocate window */
-        Term->mem = term_win::create(w, h);
+    if (Term->mem_stack.empty())
+        return 0;
+
+    if (load_all) {
+        // 残り1つを残して読み捨てる
+        while (Term->mem_stack.size() > 1)
+            Term->mem_stack.pop();
     }
 
     /* Load */
-    term_win_copy(Term->scr, Term->mem, w, h);
+    term_win_copy(Term->scr, Term->mem_stack.top(), w, h);
+
+    /* Pop stack */
+    Term->mem_stack.pop();
 
     /* Assume change */
     for (TERM_LEN y = 0; y < h; y++) {
@@ -1959,11 +1963,15 @@ errr term_resize(TERM_LEN w, TERM_LEN h)
     std::unique_ptr<term_win> hold_scr = std::move(Term->scr);
 
     /* Save old window */
-    std::unique_ptr<term_win> hold_mem = std::move(Term->mem);
-
-    /* Save old window */
     std::unique_ptr<term_win> hold_tmp = std::move(Term->tmp);
 
+    // 画面情報保存スタックをバックアップ(ウィンドウサイズが変わるので単純なムーブやコピーでは対応できない)
+    std::stack<std::unique_ptr<term_win>> hold_mem_stack;
+    while (!Term->mem_stack.empty()) {
+        hold_mem_stack.push(std::move(Term->mem_stack.top()));
+        Term->mem_stack.pop();
+    }
+
     /* Create new scanners */
     Term->x1 = std::vector<TERM_LEN>(h);
     Term->x2 = std::vector<TERM_LEN>(h);
@@ -1981,15 +1989,6 @@ errr term_resize(TERM_LEN w, TERM_LEN h)
     term_win_copy(Term->scr, hold_scr, wid, hgt);
 
     /* If needed */
-    if (hold_mem) {
-        /* Create new window */
-        Term->mem = term_win::create(w, h);
-
-        /* Save the contents */
-        term_win_copy(Term->mem, hold_mem, wid, hgt);
-    }
-
-    /* If needed */
     if (hold_tmp) {
         /* Create new window */
         Term->tmp = term_win::create(w, h);
@@ -1998,6 +1997,20 @@ errr term_resize(TERM_LEN w, TERM_LEN h)
         term_win_copy(Term->tmp, hold_tmp, wid, hgt);
     }
 
+    // 退避していた画面情報保存スタックをウィンドウサイズを変えながらリストア
+    while (!hold_mem_stack.empty()) {
+        Term->mem_stack.push(term_win::create(w, h));
+        auto &top = Term->mem_stack.top();
+        term_win_copy(top, hold_mem_stack.top(), wid, hgt);
+        hold_mem_stack.pop();
+
+        /* Illegal cursor */
+        if (top->cx >= w)
+            top->cu = 1;
+        if (top->cy >= h)
+            top->cu = 1;
+    }
+
     /* Illegal cursor */
     if (Term->old->cx >= w)
         Term->old->cu = 1;
@@ -2011,15 +2024,6 @@ errr term_resize(TERM_LEN w, TERM_LEN h)
         Term->scr->cu = 1;
 
     /* If needed */
-    if (Term->mem) {
-        /* Illegal cursor */
-        if (Term->mem->cx >= w)
-            Term->mem->cu = 1;
-        if (Term->mem->cy >= h)
-            Term->mem->cu = 1;
-    }
-
-    /* If needed */
     if (Term->tmp) {
         /* Illegal cursor */
         if (Term->tmp->cx >= w)
@@ -2201,8 +2205,9 @@ errr term_nuke(term_type *t)
 
     t->old.reset();
     t->scr.reset();
-    t->mem.reset();
     t->tmp.reset();
+    while (!t->mem_stack.empty())
+        t->mem_stack.pop();
 
     t->x1.clear();
     t->x2.clear();
index fd6a526..d1d225e 100644 (file)
@@ -15,6 +15,7 @@
 #include "system/h-basic.h"
 
 #include <memory>
+#include <stack>
 #include <vector>
 
 /*!
@@ -83,7 +84,7 @@ struct term_type {
     std::unique_ptr<term_win> scr; //!< Requested screen image
 
     std::unique_ptr<term_win> tmp; //!< Temporary screen image
-    std::unique_ptr<term_win> mem; //!< Memorized screen image
+    std::stack<std::unique_ptr<term_win>> mem_stack; //!< Memorized screen image stack
 
     void (*init_hook)(term_type *t){}; //!< Hook for init - ing the term
     void (*nuke_hook)(term_type *t){}; //!< Hook for nuke - ing the term
@@ -185,7 +186,7 @@ errr term_key_push(int k);
 errr term_inkey(char *ch, bool wait, bool take);
 
 errr term_save(void);
-errr term_load(void);
+errr term_load(bool load_all);
 
 errr term_exchange(void);