OSDN Git Service

[Refactor] トークン定義を地形関連フラグに合わせる
[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 concptr 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(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     char buf[MAIN_WIN_MAX_PATH];
81     BYTE wid, hgt, twid, thgt, ox, oy;
82     concptr name;
83     concptr name_mask = nullptr;
84
85     infGraph.delete_bitmap();
86
87     if (arg == graphics_mode::GRAPHICS_ORIGINAL) {
88         wid = 8;
89         hgt = 8;
90         twid = 8;
91         thgt = 8;
92         ox = 0;
93         oy = 0;
94         name = "8X8.BMP";
95         ANGBAND_GRAF = "old";
96     } else if (arg == graphics_mode::GRAPHICS_ADAM_BOLT) {
97         wid = 16;
98         hgt = 16;
99         twid = 16;
100         thgt = 16;
101         ox = 0;
102         oy = 0;
103         name = "16X16.BMP";
104         name_mask = "mask.bmp";
105
106         ANGBAND_GRAF = "new";
107     } else if (arg == graphics_mode::GRAPHICS_HENGBAND) {
108         wid = 32;
109         hgt = 32;
110         twid = 32;
111         thgt = 32;
112         ox = 0;
113         oy = 0;
114         name = "32X32.BMP";
115         name_mask = "mask32.bmp";
116
117         ANGBAND_GRAF = "ne2";
118     } else {
119         ANGBAND_GRAF = "ascii";
120         current_graphics_mode = graphics_mode::GRAPHICS_NONE;
121         return current_graphics_mode;
122     }
123
124     path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, name);
125     infGraph.hBitmap = read_graphic(buf);
126     if (!infGraph.hBitmap) {
127         plog_fmt(_("ビットマップ '%s' を読み込めません。", "Cannot read bitmap file '%s'"), name);
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) {
141         path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA_GRAF, name_mask);
142         infGraph.hBitmapMask = read_graphic(buf);
143         if (!infGraph.hBitmapMask) {
144             plog_fmt(_("ビットマップ '%s' を読み込めません。", "Cannot read bitmap file '%s'"), name_mask);
145             ANGBAND_GRAF = "ascii";
146             current_graphics_mode = graphics_mode::GRAPHICS_NONE;
147             return current_graphics_mode;
148         }
149     }
150
151     current_graphics_mode = arg;
152     return arg;
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 }