入力を受け付けなかった理由は,1回の割り込みの処理時間が長すぎて(≒20ms),main関数内のreadInput()内のgetch()が永遠に処理されなかったことが原因だと考えられる
- 毎フレーム全画面更新→差分更新に変更
void refreshScreen() {
redrawwin(wBattleField); // needed to display graphics properly at startup on
// some terminals
wrefresh(wBattleField);
}redrawwinの動作:
redrawwin(3XCURSES) (man pages section 3: Curses Library Functions)
redrawwinの動作
The redrawwin() function forces the entire window win to be redrawn, while the wredrawln() function forces only num_lines lines starting with beg_line to be redrawn. Normally, refresh operations use optimization methods to reduce the actual amount of the screen to redraw based on the current screen contents. These functions tell the refresh operations not to attempt any optimization when redrawing the indicated areas.
つまり,redrawwin()は強制的に全画面を再描画する指示を出すコマンド
wrefresh(3CURSES)の動作:
wrefresh(3CURSES) (man pages section 3: Curses Library Functions)
wrefresh()の動作
The routine wrefresh() works by first calling wnoutrefresh(), which copies the named window to the virtual screen, and then calling doupdate(), which compares the virtual screen to the physical screen and does the actual update. If the programmer wishes to output several windows at once, a series of calls to wrefresh() results in alternating calls to wnoutrefresh() and doupdate(), causing several bursts of output to the screen.
つまり,wrefresh()はwnoutrefresh()とdoupdate()を呼び出す関数
wnoutrefresh()は指定されたウィンドウを仮想スクリーンにコピーする関数
doupdate()は仮想スクリーンと物理スクリーンを比較して,画面を更新する関数
つまり,画面の差分更新を行う関数
元のコードは毎回,redrawwin()した後にwrefresh()していたのでdoupdate()で全画面が更新された扱いとなり,全画面が更新されてしまっていた(=表示が重い)
これを,起動直後に一回だけ全画面更新(起動直後にターミナルにゴミが残っている可能性があるため)して,そのあとは差分更新だけするようにして軽量化
- 割り込み処理を最小限に
タイマー割り込み(20ms)ごとにrefreshScreen()を呼んでいたのを,画面が更新された場合のrefreshScreen()を呼ぶように変更し,割り込みの処理を最小限にした