* @brief Windows版固有実装(メインエントリポイント含む)
* @date 2018/03/16
* @author Hengband Team
- * @todo main関数を含むファイルの割に長過ぎる。main-win-utils.cなどといった形で分割したい
* @details
*
* <h3>概要</h3>
#ifdef WINDOWS
-#include "cmd-io/cmd-process-screen.h"
#include "cmd-io/cmd-save.h"
+#include "cmd-visual/cmd-draw.h"
#include "core/game-play.h"
#include "core/player-processor.h"
#include "core/scores.h"
#include "io/record-play-movie.h"
#include "io/signal-handlers.h"
#include "io/write-diary.h"
+#include "main-win/graphics-win.h"
#include "main-win/main-win-bg.h"
#include "main-win/main-win-file-utils.h"
#include "main-win/main-win-mci.h"
#include "main-win/main-win-menuitem.h"
#include "main-win/main-win-music.h"
#include "main-win/main-win-sound.h"
+#include "main-win/main-win-utils.h"
#include "main/angband-initializer.h"
#include "main/sound-of-music.h"
#include "monster-floor/monster-lite.h"
#include "save/save.h"
-#include "system/angband-version.h"
#include "system/angband.h"
+#include "system/player-type-definition.h"
#include "system/system-variables.h"
#include "term/gameterm.h"
#include "term/screen-processor.h"
#include <commdlg.h>
#include <direct.h>
-/*
- * Include the support for loading bitmaps
- */
-#include "term/readdib.h"
-
-/*
- * Available graphic modes
- */
-#define GRAPHICS_NONE 0
-#define GRAPHICS_ORIGINAL 1
-#define GRAPHICS_ADAM_BOLT 2
-#define GRAPHICS_HENGBAND 3
-
/*!
* @struct term_data
* @brief ターム情報構造体 / Extra "term" data
*/
static HICON hIcon;
-/*
- * A palette
- */
-static HPALETTE hPal;
-
/* bg */
-enum class bg_mode {
- BG_NONE = 0,
- BG_ONE = 1,
- BG_PRESET = 2,
-};
bg_mode current_bg_mode = bg_mode::BG_NONE;
#define DEFAULT_BG_FILENAME "bg.bmp"
char wallpaper_file[MAIN_WIN_MAX_PATH] = ""; //!< 壁紙ファイル名。
static byte current_graphics_mode = 0;
/*
- * The global bitmap
+ * The global tile
*/
-static DIBINIT infGraph;
+static tile_info infGraph;
/*
- * The global bitmap mask
+ * The global tile mask
*/
-static DIBINIT infMask;
+static tile_info infMask;
/*
* Show sub-windows even when Hengband is not in focus
*/
static bool init_graphics(void)
{
- char buf[1024];
+ char buf[MAIN_WIN_MAX_PATH];
BYTE wid, hgt, twid, thgt, ox, oy;
concptr name;
+ concptr name_mask = NULL;
+
+ infGraph.delete_bitmap();
+ infMask.delete_bitmap();
if (arg_graphics == GRAPHICS_ADAM_BOLT) {
wid = 16;
ox = 0;
oy = 0;
name = "16X16.BMP";
+ name_mask = "mask.bmp";
ANGBAND_GRAF = "new";
} else if (arg_graphics == GRAPHICS_HENGBAND) {
ox = 0;
oy = 0;
name = "32X32.BMP";
+ name_mask = "mask32.bmp";
ANGBAND_GRAF = "ne2";
} else {
}
path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, name);
- if (!ReadDIB(data[0].w, buf, &infGraph)) {
+ infGraph.hBitmap = read_graphic(buf);
+ if (!infGraph.hBitmap) {
plog_fmt(_("ビットマップ '%s' を読み込めません。", "Cannot read bitmap file '%s'"), name);
return FALSE;
}
infGraph.OffsetX = ox;
infGraph.OffsetY = oy;
- if (arg_graphics == GRAPHICS_ADAM_BOLT) {
- path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, "mask.bmp");
- if (!ReadDIB(data[0].w, buf, &infMask)) {
- plog_fmt("Cannot read bitmap file '%s'", buf);
- return FALSE;
- }
- }
-
- if (arg_graphics == GRAPHICS_HENGBAND) {
- path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, "mask32.bmp");
- if (!ReadDIB(data[0].w, buf, &infMask)) {
+ if (name_mask) {
+ path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, name_mask);
+ infMask.hBitmap = read_graphic(buf);
+ if (!infMask.hBitmap) {
plog_fmt("Cannot read bitmap file '%s'", buf);
return FALSE;
}
}
}
+/*!
+ * @brief Change sound mode
+ * @param new_mode bool
+ */
+static void change_sound_mode(bool new_mode)
+{
+ use_sound = new_mode;
+ if (use_sound) {
+ init_sound();
+ }
+}
+
/*
* Initialize background
*/
* @brief Change background mode
* @param new_mode bg_mode
* @param show_error trueに設定した場合のみ、エラーダイアログを表示する
+ * @param force_redraw trueの場合、モード変更に関わらずウインドウを再描画する
* @retval true success
* @retval false failed
*/
-static bool change_bg_mode(bg_mode new_mode, bool show_error = false)
+static bool change_bg_mode(bg_mode new_mode, bool show_error = false, bool force_redraw = false)
{
+ bg_mode old_bg_mode = current_bg_mode;
current_bg_mode = new_mode;
if (current_bg_mode != bg_mode::BG_NONE) {
init_background();
delete_bg();
}
+ const bool mode_changed = (current_bg_mode != old_bg_mode);
+ if (mode_changed || force_redraw) {
+ // 全ウインドウ再描画
+ for (int i = 0; i < MAX_TERM_DATA; i++) {
+ term_data *td = &data[i];
+ if (td->visible)
+ InvalidateRect(td->w, NULL, FALSE);
+ }
+ }
+
return (current_bg_mode == new_mode);
}
return 0;
}
-static void refresh_color_table() {
+static void refresh_color_table()
+{
for (int i = 0; i < 256; i++) {
byte rv = angband_color_table[i][1];
byte gv = angband_color_table[i][2];
{
refresh_color_table();
- use_sound = arg_sound;
- if (use_sound) {
- init_sound();
- }
-
- if (use_graphics != (arg_graphics > 0)) {
- if (arg_graphics && !init_graphics()) {
- plog(_("グラフィックスを初期化できません!", "Cannot initialize graphics!"));
- arg_graphics = GRAPHICS_NONE;
- }
-
- use_graphics = (arg_graphics > 0);
- reset_visuals(player_ptr);
+ if (arg_graphics && !init_graphics()) {
+ plog(_("グラフィックスを初期化できません!", "Cannot initialize graphics!"));
+ arg_graphics = GRAPHICS_NONE;
}
+ use_graphics = (arg_graphics > 0);
+ reset_visuals(player_ptr);
for (int i = 0; i < MAX_TERM_DATA; i++) {
term_type *old = Term;
case IDM_OPTIONS_NO_GRAPHICS: {
if (arg_graphics != GRAPHICS_NONE) {
arg_graphics = GRAPHICS_NONE;
-
- if (inkey_flag) {
- term_xtra_win_react(player_ptr);
- term_key_push(KTRL('R'));
- }
+ if (game_in_progress)
+ do_cmd_redraw(player_ptr);
}
break;
}
case IDM_OPTIONS_OLD_GRAPHICS: {
if (arg_graphics != GRAPHICS_ORIGINAL) {
arg_graphics = GRAPHICS_ORIGINAL;
-
- if (inkey_flag) {
- term_xtra_win_react(player_ptr);
- term_key_push(KTRL('R'));
- } else if (!init_graphics()) {
- arg_graphics = GRAPHICS_NONE;
- }
+ if (game_in_progress)
+ do_cmd_redraw(player_ptr);
}
break;
case IDM_OPTIONS_NEW_GRAPHICS: {
if (arg_graphics != GRAPHICS_ADAM_BOLT) {
arg_graphics = GRAPHICS_ADAM_BOLT;
-
- if (inkey_flag) {
- term_xtra_win_react(player_ptr);
- term_key_push(KTRL('R'));
- } else if (!init_graphics()) {
- arg_graphics = GRAPHICS_NONE;
- }
+ if (game_in_progress)
+ do_cmd_redraw(player_ptr);
}
break;
case IDM_OPTIONS_NEW2_GRAPHICS: {
if (arg_graphics != GRAPHICS_HENGBAND) {
arg_graphics = GRAPHICS_HENGBAND;
-
- if (inkey_flag) {
- term_xtra_win_react(player_ptr);
- term_key_push(KTRL('R'));
- } else if (!init_graphics()) {
- arg_graphics = GRAPHICS_NONE;
- }
+ if (game_in_progress)
+ do_cmd_redraw(player_ptr);
}
break;
}
case IDM_OPTIONS_SOUND: {
arg_sound = !arg_sound;
- if (inkey_flag)
- term_xtra_win_react(player_ptr);
+ change_sound_mode(arg_sound);
break;
}
case IDM_OPTIONS_NO_BG: {
change_bg_mode(bg_mode::BG_NONE);
- td = &data[0];
- InvalidateRect(td->w, NULL, TRUE);
break;
}
case IDM_OPTIONS_PRESET_BG: {
change_bg_mode(bg_mode::BG_PRESET);
- td = &data[0];
- InvalidateRect(td->w, NULL, TRUE);
break;
}
case IDM_OPTIONS_BG: {
- bool ret = change_bg_mode(bg_mode::BG_ONE);
- if (ret) {
- td = &data[0];
- InvalidateRect(td->w, NULL, TRUE);
+ if (change_bg_mode(bg_mode::BG_ONE))
break;
- }
// 壁紙の設定に失敗した(ファイルが存在しない等)場合、壁紙に使うファイルを選択させる
}
[[fallthrough]]; /* Fall through */
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
if (GetOpenFileName(&ofn)) {
- change_bg_mode(bg_mode::BG_ONE, true);
- td = &data[0];
- InvalidateRect(td->w, NULL, TRUE);
+ change_bg_mode(bg_mode::BG_ONE, true, true);
}
break;
}
case IDM_DUMP_SCREEN_HTML: {
- static char buf[1024] = "";
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = data[0].w;
- ofn.lpstrFilter = "HTML Files (*.html)\0*.html\0";
- ofn.nFilterIndex = 1;
- ofn.lpstrFile = buf;
- ofn.nMaxFile = 1023;
- ofn.lpstrDefExt = "html";
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = _("HTMLでスクリーンダンプを保存", "Save screen dump as HTML.");
- ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
-
- if (GetSaveFileName(&ofn)) {
- do_cmd_save_screen_html_aux(buf, 0);
- }
-
+ save_screen_as_html(data[0].w);
break;
}
}
}
/*!
- * @todo WNDCLASSに影響があるのでplayer_type*の追加は保留
+ * @brief メインウインドウ用ウインドウプロシージャ
*/
LRESULT PASCAL AngbandWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
for (int i = 0; i < dy; i++) {
#ifdef JP
char *s;
- char **scr = data[0].t.scr->c;
+ const auto &scr = data[0].t.scr->c;
C_MAKE(s, (dx + 1), char);
strncpy(s, &scr[oy + i][ox], dx);
}
/*!
- * @todo WNDCLASSに影響があるのでplayer_type*の追加は保留
+ * @brief サブウインドウ用ウインドウプロシージャ
*/
LRESULT PASCAL AngbandListProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static void hack_plog(concptr str)
{
if (str) {
-#ifdef JP
- MessageBox(NULL, str, "警告!", MB_ICONEXCLAMATION | MB_OK);
-#else
- MessageBox(NULL, str, "Warning", MB_ICONEXCLAMATION | MB_OK);
-#endif
+ MessageBoxW(NULL, to_wchar(str).wc_str(), _(L"警告!", L"Warning"), MB_ICONEXCLAMATION | MB_OK);
}
}
static void hack_quit(concptr str)
{
if (str) {
-#ifdef JP
- MessageBox(NULL, str, "エラー!", MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
-#else
- MessageBox(NULL, str, "Error", MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
-#endif
+ MessageBoxW(NULL, to_wchar(str).wc_str(), _(L"エラー!", L"Error"), MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
}
UnregisterClass(AppName, hInstance);
static void hook_plog(concptr str)
{
if (str) {
-#ifdef JP
- MessageBox(data[0].w, str, "警告!", MB_ICONEXCLAMATION | MB_OK);
-#else
- MessageBox(data[0].w, str, "Warning", MB_ICONEXCLAMATION | MB_OK);
-#endif
+ MessageBoxW(data[0].w, to_wchar(str).wc_str(), _(L"警告!", L"Warning"), MB_ICONEXCLAMATION | MB_OK);
}
}
static void hook_quit(concptr str)
{
if (str) {
-#ifdef JP
- MessageBox(data[0].w, str, "エラー!", MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
-#else
- MessageBox(data[0].w, str, "Error", MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
-#endif
+ MessageBoxW(data[0].w, to_wchar(str).wc_str(), _(L"エラー!", L"Error"), MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
}
save_prefs();
data[i].w = 0;
}
- if (infGraph.hPalette)
- DeleteObject(infGraph.hPalette);
- if (infGraph.hBitmap)
- DeleteObject(infGraph.hBitmap);
- if (infMask.hPalette)
- DeleteObject(infMask.hPalette);
- if (infMask.hBitmap)
- DeleteObject(infMask.hBitmap);
+ infGraph.delete_bitmap();
+ infMask.delete_bitmap();
DeleteObject(hbrYellow);
finalize_bg();
-
- if (hPal)
- DeleteObject(hPal);
+ finalize_graphics();
UnregisterClass(AppName, hInstance);
if (hIcon)
}
/*!
- * @todo よく見るとhMutexはちゃんと使われていない……?
- * @brief (Windows固有)変愚蛮怒が起動済かどうかのチェック
- */
-static bool is_already_running(void)
-{
- HANDLE hMutex;
- hMutex = CreateMutex(NULL, TRUE, VERSION_NAME);
- if (GetLastError() == ERROR_ALREADY_EXISTS) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*!
* @brief (Windows固有)Windowsアプリケーションとしてのエントリポイント
*/
int WINAPI WinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInst, _In_ LPSTR lpCmdLine, [[maybe_unused]] _In_ int nCmdShow)
setlocale(LC_ALL, "ja_JP");
hInstance = hInst;
if (is_already_running()) {
- MessageBox(
- NULL, _("変愚蛮怒はすでに起動しています。", "Hengband is already running."), _("エラー!", "Error"), MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
+ MessageBoxW(
+ NULL, _(L"変愚蛮怒はすでに起動しています。", L"Hengband is already running."), _(L"エラー!", L"Error"), MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
return FALSE;
}
prt(_("[ファイル] メニューの [新規] または [開く] を選択してください。", "[Choose 'New' or 'Open' from the 'File' menu]"), 23, _(8, 17));
term_fresh();
+ change_sound_mode(arg_sound);
use_music = arg_music;
if (use_music) {
init_music();