OSDN Git Service

Merge branch 'develop' into macos-develop
[hengbandforosx/hengbandosx.git] / src / main-win / graphics-win.cpp
1 /*!
2  * @file graphics-win.cpp
3  * @brief Windows版固有実装(タイル、イメージファイルの読み込み)
4  */
5
6 #include "main-win/graphics-win.h"
7 #include "main-win/main-win-define.h"
8 #include "main-win/main-win-utils.h"
9 #include "system/system-variables.h"
10 #include "util/angband-files.h"
11
12 #pragma warning(push)
13 #pragma warning(disable : 4458)
14 #include <gdiplus.h>
15 #pragma warning(pop)
16
17 // Flag set once "GDI+" has been initialized
18 bool gdi_plus_started = false;
19 // a token for "GDI+"
20 ULONG_PTR gdiplusToken;
21
22 // interface object
23 Graphics graphic{};
24
25 std::filesystem::path ANGBAND_DIR_XTRA_GRAF;
26
27 /*!
28  * 現在使用中のタイルID(0ならば未使用)
29  */
30 static graphics_mode current_graphics_mode = graphics_mode::GRAPHICS_NONE;
31
32 /*
33  * The global tile
34  */
35 static tile_info infGraph;
36
37 /*!
38  * @brief Initialize GDI+
39  */
40 static inline void init_gdi_plus()
41 {
42     if (!gdi_plus_started) {
43         Gdiplus::GdiplusStartupInput gdiplusStartupInput;
44         Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
45         gdi_plus_started = true;
46     }
47 }
48
49 /*!
50  * @brief Cleans up resources used by GDI+
51  */
52 static void finalize_gdi_plus()
53 {
54     if (gdi_plus_started) {
55         Gdiplus::GdiplusShutdown(gdiplusToken);
56         gdi_plus_started = false;
57     }
58 }
59
60 HBITMAP read_graphic(const char *filename)
61 {
62     HBITMAP result = NULL;
63     init_gdi_plus();
64
65     Gdiplus::Bitmap bitmap(to_wchar(filename).wc_str());
66
67     COLORREF bgcolor = RGB(0x00, 0x00, 0x00);
68     bitmap.GetHBITMAP(bgcolor, &result);
69
70     return result;
71 }
72
73 namespace Impl {
74 graphics_mode change_graphics(graphics_mode arg)
75 {
76     if (current_graphics_mode == arg) {
77         return current_graphics_mode;
78     }
79
80     BYTE wid, hgt, twid, thgt, ox, oy;
81     std::string name;
82     std::string name_mask("");
83
84     infGraph.delete_bitmap();
85
86     if (arg == graphics_mode::GRAPHICS_ORIGINAL) {
87         wid = 8;
88         hgt = 8;
89         twid = 8;
90         thgt = 8;
91         ox = 0;
92         oy = 0;
93         name = "8X8.BMP";
94         ANGBAND_GRAF = "old";
95     } else if (arg == graphics_mode::GRAPHICS_ADAM_BOLT) {
96         wid = 16;
97         hgt = 16;
98         twid = 16;
99         thgt = 16;
100         ox = 0;
101         oy = 0;
102         name = "16X16.BMP";
103         name_mask = "16x16-mask.bmp";
104
105         ANGBAND_GRAF = "new";
106     } else if (arg == graphics_mode::GRAPHICS_HENGBAND) {
107         wid = 32;
108         hgt = 32;
109         twid = 32;
110         thgt = 32;
111         ox = 0;
112         oy = 0;
113         name = "32X32.BMP";
114         name_mask = "mask32.bmp";
115
116         ANGBAND_GRAF = "ne2";
117     } else {
118         ANGBAND_GRAF = "ascii";
119         current_graphics_mode = graphics_mode::GRAPHICS_NONE;
120         return current_graphics_mode;
121     }
122
123     const auto &path = path_build(ANGBAND_DIR_XTRA_GRAF, name);
124     const auto &filename = path.string();
125     infGraph.hBitmap = read_graphic(filename.data());
126     if (!infGraph.hBitmap) {
127         plog_fmt(_("ビットマップ '%s' を読み込めません。", "Cannot read bitmap file '%s'"), name.data());
128         ANGBAND_GRAF = "ascii";
129         current_graphics_mode = graphics_mode::GRAPHICS_NONE;
130         return current_graphics_mode;
131     }
132
133     infGraph.CellWidth = wid;
134     infGraph.CellHeight = hgt;
135     infGraph.TileWidth = twid;
136     infGraph.TileHeight = thgt;
137     infGraph.OffsetX = ox;
138     infGraph.OffsetY = oy;
139
140     if (name_mask.empty()) {
141         const auto &path_mask = path_build(ANGBAND_DIR_XTRA_GRAF, name_mask);
142         const auto &filename_mask = path_mask.string();
143         infGraph.hBitmapMask = read_graphic(filename_mask.data());
144         if (!infGraph.hBitmapMask) {
145             plog_fmt(_("ビットマップ '%s' を読み込めません。", "Cannot read bitmap file '%s'"), name_mask.data());
146             ANGBAND_GRAF = "ascii";
147             current_graphics_mode = graphics_mode::GRAPHICS_NONE;
148             return current_graphics_mode;
149         }
150     }
151
152     current_graphics_mode = arg;
153     return arg;
154 }
155 }
156
157 graphics_mode Graphics::get_mode(void)
158 {
159     return current_graphics_mode;
160 }
161
162 graphics_mode Graphics::change_graphics(graphics_mode arg)
163 {
164     return Impl::change_graphics(arg);
165 }
166
167 const tile_info &Graphics::get_tile_info(void)
168 {
169     return infGraph;
170 }
171
172 void Graphics::init(void)
173 {
174     init_gdi_plus();
175 }
176
177 void Graphics::finalize()
178 {
179     infGraph.delete_bitmap();
180     finalize_gdi_plus();
181 }