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